C#“是”运算符 – 是reflection吗?

一位同事今天问我一个有趣的问题 – C#关键字/运营商“是否被认为是反思?

object tmp = "a string"; if(tmp is String) { } 

这个操作符是如何在幕后实现的? 它需要反思还是反省? 或者由于语言的强类型性质,对象的类型是否可以作为内存中对象的顶级属性立即访问?

MSDN声明:

请注意,is运算符仅考虑引用转换,装箱转换和拆箱转换。 is运算符不考虑其他转换,例如用户定义的转换。

考虑盒装和非盒装转换的能力似乎意味着我某种内省。

引用ECMA-335时 , is运算符生成isinst对象模型IL指令(PartitionIII§4.6),它是基本指令集的一部分,而不是作为Reflection库的一部分(PartitionIV§5.5)。

编辑:与reflection库相比, is运算符非常有效。 您可以通过reflection更慢地执行基本相同的测试:

 typeof(T).IsAssignableFrom(obj.GetType()) 

编辑2:关于castclassisinst指令的效率你是不正确的(你现在已经在post中编辑过了)。 它们在任何实际的VM实现中都经过高度优化。 所涉及的唯一真正的性能问题是castclass抛出exception的可能性,通过使用C# as运算符和null (对于引用类型)的测试或者is运算符后跟cast(对于值类型),可以避免这种情况。

is运算符实质上决定了是否可以进行强制转换,但是当不能进行强制转换时,它不会抛出exception,而是返回false 。 如果你考虑投射reflection,那么这也是reflection。

编辑:

经过一些研究后,我发现一个castclass在IL中执行了castclass指令,而is运算符映射到了isinst指令。 FxCop有一条规则 ,如果您通过首先使用isinst然后使用castclass指令进行不必要的强制转换,则会向您发出警告。 即使操作有效,它们仍然具有性能成本。

其他语言具有足以支持动态转换的运行时信息,但没有任何可以被描述为reflection(C ++是一个明显的例子)。

因此,reflection是指除了发现对象类型之外的其他function。 例如,要“反映”一个物体意味着能够走路。