如果不需要转换,并且需要检查对象的最具体(运行时)类型,哪个更快? .GetType() & typeof(),还是运算符?

If you need no casting, and you need to check the most specific (runtime) type of an object, which is faster? .GetType() & typeof(), or is operator?

1) .GetType() 将 return 调用它的对象的运行时类型, 这是继承层次结构中最具体的类型。您可以使用 typeof() 为类名
获取 Type 的函数 2) is 运算符将检查左侧对象的类型 是右侧指定类型的子类型或相同类型
3) 鉴于您只需要检查对象的最具体类型,并且不需要转换,前者 (1) 是否比后者 (2) 快得多?
4) is 运算符是否实际执行转换并检查是否为 null,或者 此行为已在更高版本的 C Sharp 中修改?

typeof(x)就是得到一个Literal类型的Type-Object,比如typeof(int)。这是一个运行时常量。

对于 object.GetType() 你需要一个对象实例。

 if (x is IList)

is 运算符进行强制转换,但 returns bool 表示成功,如果 x 为 null 或不兼容类型,则为 false。 有

 if (x is IList list)

您可以同时进行布尔测试和转换。

没意义,谈性能,因为完全不同的操作。

如果你想获取对象实例的类型 object.GetType() 是你唯一的选择,但你可以再次测试它,如

 x.GetType() == typeof(List)

虽然你可以确定

 x.GetType() == typeof(IList)

将始终为 false,因为 GetType 永远不会 return 接口的类型。 对于此测试,您需要

typeof(IList).IsAssignableFrom(x.GetType());

第一个 4) 因为它更简单。 is 运算符与 as 运算符一起实现。

x is C

相同
x as C != null

源码可以看the fabulous Eric Lippert's blog。目前(提交 e09c42a),Roslyn 编译器将两者都转换为

isinst C
ldnull
cgt.un

其中 isinst 是尝试将 x 转换为 C 并将转换后的引用留在堆栈顶部的魔法指令,如果失败则为 null .剩下的两条指令是检查 null.

至于性能,不好说。理论上,使用 is 检查应该更快,因为它是一个内置的 CLR 指令,针对它的作用进行了高度优化,而另一个检查必须调用三种方法,GetType()GetTypeFromHandle(RuntimeTypeHandle)Type 上的等式。还有涉及调用 GetType() 的标准检查 null 和抛出 NRE。一个非常粗略的基准支持这个假设:link to DotNetFiddle。如果有人愿意执行更复杂的基准测试,请继续。

显然,我可以想象您可以拥有如此深和复杂的继承层次结构,is 检查将比 GetType() 的任何开销花费更长的时间。随意将我的基准子类型提高到 C100 并检查是否足够:)

编辑: 我想我应该补充一点,这个讨论纯粹是理论上的。在生产代码中,您应该使用 x is C,因为它简洁且更健壮,因为它会检查整个层次结构以进行子类型化。如果您有一个热路径来检查给定实例的类型,并且您知道层次结构是扁平的,那么您可能应该重新设计系统以避免该检查,而不是通过丑化代码来挤出一些性能。