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



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

typeof(x)是获取文本类型的Type-Object,如typeof(int)。这是一个运行时常量。

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

if (x is IList)

is 运算符执行强制转换,但如果 x 为 null 或不兼容的类型,则在成功时返回 bool 或 false。 跟

if (x is IList list)

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

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

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

x.GetType() == typeof(List)

虽然你可以确定

x.GetType() == typeof(IList)

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

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

前 4 个(,因为它更简单。is运算符与as运算符一起实现。

x is C

x as C != null

对于来源,您可以查看神话般的Eric Lippert的博客。目前(提交 e09c42a(,Roslyn 编译器将两者转换为

isinst C
ldnull
cgt.un

其中isinst是尝试将x转换为C并将强制转换的引用保留在堆栈顶部的神奇指令,如果失败,则null。剩下的两个指令是检查null

至于性能,很难肯定地说。从理论上讲,使用is进行检查应该更快,因为它是一个内置的 CLR 指令,针对它的功能进行了大量优化,而另一个检查必须调用三种方法,即GetType()GetTypeFromHandle(RuntimeTypeHandle)Type上的相等。还有与调用GetType()有关的标准检查空和抛出 NRE 。一个非常粗略的基准支持这个假设:链接到DotNetFiddle。如果有人愿意执行更复杂的基准测试,请继续。

显然,我可以想象您的继承层次结构如此深入和复杂,以至于is检查所需的时间将超过GetType()的任何开销。随意将我的基准测试子类型到 C100,并检查这是否足够:)

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

最新更新