[英]typeof(T) vs. Object.GetType() performance
有没有人知道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 的本机代码中定义的。 所以,我只是想知道是否有人知道有任何理由喜欢一个而不是另一个?
编辑:让我澄清一下,我最感兴趣的是您选择哪个似乎无关紧要的情况 - 也就是说,是否存在性能差异或任何其他原因? 谢谢!
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
方法中,您正在处理类型A
实例; 因此,如果您关心声明的类型,则可以使用typeof(A)
。 但是,尽管将基类声明为返回类型,但CreateA
方法实际上返回派生类B
的实例。 如果您想了解此运行时类型,请对返回的实例调用GetType
。
编辑:Mehrdad 的评论指向正确的方向。 尽管typeof
发出一个GetTypeFromHandle
调用,该调用将RuntimeTypeHandle
作为参数,但该参数实际上对应于元数据标记位于评估堆栈上的特定类型。 在某些情况下,这个标记会隐式存在(由于当前的方法调用); 否则,它可以通过调用ldtoken显式推送到那里。 你可以在这些答案中看到更多这样的例子:
编辑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()
在编译时解析。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.