C#"是"运算符 - 是反射吗?

Mat*_*att 29 .net c# reflection introspection typing

一位同事今天问我一个有趣的问题 - C#关键字/运算符"是否被认为是反思?

object tmp = "a string";
if(tmp is String)
{
}
Run Code Online (Sandbox Code Playgroud)

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

MSDN声明:

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

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

Sam*_*ell 35

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

编辑:is与反射库相比,操作员非常高效.您可以通过反射更慢地执行基本相同的测试:

typeof(T).IsAssignableFrom(obj.GetType())
Run Code Online (Sandbox Code Playgroud)

编辑2:你是不是对的效率正确castclassisinst指令(你现在已经编辑了帖子).它们在任何实际的VM实现中都经过高度优化.所涉及的唯一真正的性能问题是castclass抛出异常的可能性,可以通过使用C#as运算符和null(对于引用类型)或is运算符后跟转换(对于值类型)来避免.

  • 正如我在第二次编辑中提到的那样,你应该使用`as`后跟`null`检查引用类型.你改为使用`is`后面跟一个演员,这就是FxCop提醒你的. (2认同)
  • 对于它的价值,在Compact Framework上,需要显式检查RTTI的IL(例如`isinst`和`castclass`)和反射一样慢,而callvirt是高度优化的.道德:尽量避免使用虚拟/抽象方法可以工作的类型案例结构. (2认同)

Mar*_*age 5

is运营商基本确定是否转换是可能的,但不是当演员是不可能的,它返回抛出异常false.如果你考虑投射反射,那么这也是反射.

编辑:

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