typeof(T)与Object.GetType()性能
是否有人知道typeof(T) where T : struct
之间的任何差异,例如typeof(T) where T : struct
与t.GetType() where t is a System.Object
?
ILdasm显示typeof(T)使用System.Type::GetTypeFromHandle(RuntimeTypeHandle handle)
,另一个只是普通的System.Object::GetType()
。 实现是[MethodImpl(MethodImplOptions.InternalCall)]
,因此方法在CLR中的本机代码中定义。 所以,我只是想知道是否有人知道任何理由更喜欢一个而不是另一个?
编辑:让我澄清一点,我最感兴趣的是你选择哪个似乎没关系的情况 – 也就是说,是否存在性能差异或任何其他原因? 谢谢!
当您想要获取表示特定类型的Type
实例时,使用typeof
。 GetType
给出了调用它的对象的运行时类型,它可能与声明的类型不同。
例如:
class A {} class B : A {} class Program { static A CreateA() { return new B(); } static void Main() { A a = CreateA(); Console.WriteLine(typeof(A)); // Writes "A" Console.WriteLine(a.GetType()); // Writes "B" } }
在上面的例子中,在Main
方法中,你正在处理类型A
实例; 因此,如果您关心声明的类型,您将使用typeof(A)
。 但是,尽管将基类声明为返回类型, CreateA
方法实际上返回派生类B
的实例。 如果要查找有关此运行时类型的信息,请在返回的实例上调用GetType
。
编辑 :Mehrdad的评论指向了正确的方向。 尽管typeof
发出GetTypeFromHandle
调用,该调用将RuntimeTypeHandle
作为参数,但所述参数实际上对应于其元数据标记位于评估堆栈上的特定类型。 在某些情况下,此标记将隐式存在(由于当前方法调用); 否则,可以通过调用ldtoken显式地将其推送到那里。 您可以在以下答案中看到更多此示例:
- C#类型的运算符的效率(或其在MSIL中的任何表示)
- 为2Darrays生成IL
编辑2 :如果您正在寻找性能基准测试,可以参考Jon Skeet的答案 。 他的结果是:
typeof(Test): 2756ms test.GetType(): 3734ms
好吧,有时在通用代码中,您知道类型参数T
的编译时类型,而没有实例。 然后你必须使用typeof(T)
。
在其他时候,通常在非通用代码中,您可能对对象的运行时类型感兴趣。 然后使用GetType()
。
因此,在某些情况下,根据您想要了解的内容或您可以查询的内容,您只有一个选项。
有时候,你可以选择。
如果需要编译时信息,可以使用typeof,当需要运行时信息时,可以使用GetType。
如果您处于可以使用其中任何一种的情况,则应使用typeof,因为它可以在编译时解析。 这使得类型值更清晰,并且(原则上)允许更多优化。
typeof关键字采用编译时类型标识符,并为您提供Type的相应运行时实例:
Type intType = typeof(int); Type stringType = typeof(string); Type objectType = typeof(object); Type genericType = typeof(T); // not permitted: typeof(1), typeof(someVariable)
GetType实例方法采用运行时实例并告诉您其确切的运行时类型:
Type intType = 1.GetType(); // typeof(int) Type objectType = new Object().GetType(); // typeof(object) object x = "test"; Type stringType = x.GetType(); // typeof(string), NOT typeof(object) // not permitted: int.GetType(), string.GetType(), T.getType()
您通常只需要在编写reflection内容时使用typeof或GetType,手动创建表达式树,或使用可怕的Enum方法(采用Type实例而不是generics类型参数)。
GetType()
用于检索您实际拥有的实例类型,但是用于获取实例类型的typeof()
, GetType()
在运行时获得解析,而typeof()
在编译时解析。