typeof(T) vs. Object.GetType() performance

本文关键字:GetType performance Object vs typeof | 更新日期: 2023-09-27 18:21:08

有人知道CCD_,例如相对于t.GetType() where t is a System.Object
ILdasm表明typeof(T)使用System.Type::GetTypeFromHandle(RuntimeTypeHandle handle),而另一个只是普通的System.Object::GetType()。实现方式是CCD_ 5,因此这些方法是在CLR中的本机代码中定义的。所以,我只是想知道是否有人知道有什么理由喜欢其中一个而不是另一个?

编辑:让我澄清一下,我最感兴趣的是那些你选择哪一个似乎并不重要的情况——也就是说,是否存在性能差异或任何其他原因?谢谢

typeof(T) vs. Object.GetType() performance

typeof用于获取表示特定类型的Type实例。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方法中,您正在处理类型为typeof(T) where T : struct0的实例;因此,如果您关心声明的类型,那么您将使用typeof(A)。然而,CreateA方法实际上返回派生类B的实例,尽管声明基类为返回类型。如果您想了解此运行时类型,请对返回的实例调用GetType

编辑:Mehrdad的评论指向了正确的方向。尽管typeof发出以RuntimeTypeHandle为参数的GetTypeFromHandle调用,但所述参数实际上将对应于其元数据令牌在评估堆栈上的特定类型。在某些情况下,该令牌将隐式存在(由于当前方法调用);否则,可以通过调用ldtoken显式地将其推送到那里。你可以在这些答案中看到更多这样的例子:

  • C#类型运算符的效率(或MSIL中的任何表示)
  • 为2D阵列生成IL

编辑2:如果您正在寻找性能基准,可以参考Jon Skeet的答案。他的结果是(1亿次迭代):

typeof(Test):   2756ms
test.GetType(): 3734ms

好吧,有时在泛型代码中,您可以从类型参数T中知道编译时类型,而不需要实例。那么您必须使用typeof(T)

在其他时候,通常在非泛型代码中,您可能对对象的运行时类型感兴趣。然后使用GetType()

因此,在某些情况下,根据您想知道的内容或可以查询的内容,您只有一个选项。

有时,你可以选择。

当需要编译时信息时使用typeof,当需要运行时信息时则使用GetType。

如果您处于可以使用其中一种的情况,则应该使用typeof,因为它可以在编译时解析。这使Type值更加清晰,并且(原则上)允许进行更多优化。

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()

通常,您只需要在编写进行反射的东西、手动创建表达式树或使用糟糕的Enum方法(使用Type的实例而不是泛型类型参数)时使用typeof或GetType。

GetType()用于检索实际拥有的实例类型,但typeof()用于获取您没有的实例类型。GetType()在运行时解析,而typeof()在编译时解析。