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
用于获取表示特定类型的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 : struct
0的实例;因此,如果您关心声明的类型,那么您将使用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()
在编译时解析。