typeof(T)与Object.GetType()性能

是否有人知道typeof(T) where T : struct之间的任何差异,例如typeof(T) where T : structt.GetType() where t is a System.Object
ILdasm显示typeof(T)使用System.Type::GetTypeFromHandle(RuntimeTypeHandle handle) ,另一个只是普通的System.Object::GetType() 。 实现是[MethodImpl(MethodImplOptions.InternalCall)] ,因此方法在CLR中的本机代码中定义。 所以,我只是想知道是否有人知道任何理由更喜欢一个而不是另一个?

编辑:让我澄清一点,我最感兴趣的是你选择哪个似乎没关系的情况 – 也就是说,是否存在性能差异或任何其他原因? 谢谢!

当您想要获取表示特定类型的Type实例时,使用typeofGetType给出了调用它的对象的运行时类型,它可能与声明的类型不同。

例如:

 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()在编译时解析。