首先提个问题:is关键字是编译器决定,还是运行时决定?
is :检查对象是否与给定类型兼容。
如果所提供的表达式非空,并且所提供的对象可以强制转换为所提供的类型而不会导致引发异常,则 is 表达式的计算结果将是 true。
如果已知表达式将始终是 true 或始终是 false,则 is 关键字将导致编译时警告,但是,通常在运行时才计算类型兼容性。
不能重载 is 运算符。
请注意,is 运算符只考虑引用转换、装箱转换和取消装箱转换。不考虑其他转换,如用户定义的转换。
在 is 运算符的左侧不允许使用匿名方法。lambda 表达式属于例外。
as
as 运算符用于在兼容的引用类型之间执行转换。
as 运算符类似于强制转换操作。但是,如果无法进行转换,则 as 返回 null 而非引发异常。
除上面MS官方所说之外,通过IL,我们可以看出,用is表达式生成的语句更为简洁。
比如类型判等:
if (s is father)
{
f = s as mother;
}
生成的IL代码如下 :

Code
L_0013: ldloc.2 /*载入变量 s
L_0014: ldnull *载入空值 if(s is father)语句拆解
L_0015: ceq *判等*/
L_0017: stloc.3
L_0018: ldloc.3
L_0019: brtrue.s L_001f
L_001b: nop
L_001c: ldloc.2
L_001d: stloc.1
L_001e: nop
使用typeof和GetType()
if (s.GetType() == typeof(father))
{
f = s as mother;
}
生成IL如下:

Code
L_001f: ldloc.2
L_0020: callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
L_0025: ldtoken int32
L_002a: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)//调用了GetType和GetTypeFromHandle,执行效率上变低了。
L_002f: ceq
显然执行效率上is快了。
posted @ 2009-06-19 16:03 gecko 阅读(58) 评论(1)
编辑