繁体   English   中英

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

[英]typeof(T) vs. Object.GetType() performance

有没有人知道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 的本机代码中定义的。 所以,我只是想知道是否有人知道有任何理由喜欢一个而不是另一个?

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

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM