一位同事问我今天一个有趣的问题 - 是C#的关键字/操作员“被”认为是反映?
object tmp = "a string";
if(tmp is String)
{
}
这是如何操作的幕后实现的? 是否需要反思或反省? 或者是因为语言的强类型的性质,是物体立即accessable在内存中的对象的顶级属性的类型?
MSDN指出:
需要注意的是,就是运营商只考虑引用转换,装箱转换和取消装箱转换。 其他转换,如用户定义的转换,都没有由IS操作者考虑。
考虑装箱和取消装箱转换的能力,似乎在暗示我某种反省的。
参考ECMA-335中, is
操作者产生isinst
对象模型IL指令(分区III§4.6),这是相对于作为反射库(分区IV§5.5)的一部分设置的基本指令的一部分。
编辑: is
相对于反射库操作是非常有效的。 你可以基本上要慢得多通过反射进行相同的测试:
typeof(T).IsAssignableFrom(obj.GetType())
编辑2:你是不是对的效率正确castclass
和isinst
指令(你现在已经编辑了帖子)。 他们在任何实际的虚拟机实现高度优化。 涉及到的唯一真正的性能问题是潜在的castclass
抛出异常,您避免使用C# as
运营商和测试null
(引用类型),或者is
运营商,然后浇铸(值类型)。
的is
运营商基本确定是否转换是可能的,但不是当演员是不可能引发异常则返回false
。 如果考虑铸造反射那么这也是一个令人沉思。
编辑:
经过一番研究,我发现,铸造在IL进行帕castclass
而指令is
操作映射到isinst
指令。 的FxCop有一个规则 ,警告你,如果你是第一次使用做不必要的铸件isinst
然后castclass
指令。 虽然操作是有效的,他们还是有性能开销。
其它语言具有足以支持动态铸造运行时的时间信息,并且可以被描述为反射又没什么(C ++是一个明显的例子)。
因此,反思是指额外的功能超越仅仅发现一个对象的类型。 为了“反映”上的对象意味着走它的成员,例如能力。