简体   繁体   English

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

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

Is anyone aware of any differences between typeof(T) where T : struct , for example, vs. t.GetType() where t is a System.Object ?有没有人知道typeof(T) where T : structt.GetType() where t is a System.Object之间的任何区别?
ILdasm shows that typeof(T) uses System.Type::GetTypeFromHandle(RuntimeTypeHandle handle) , and the other is just plain System.Object::GetType() . ILdasm 显示 typeof(T) 使用System.Type::GetTypeFromHandle(RuntimeTypeHandle handle) ,而另一个只是简单的System.Object::GetType() The implementations are [MethodImpl(MethodImplOptions.InternalCall)] , so the methods are defined in native code in the CLR.实现是[MethodImpl(MethodImplOptions.InternalCall)] ,因此这些方法是在 CLR 的本机代码中定义的。 So, I'm just wondering if anyone is aware of any reason to prefer one over the other?所以,我只是想知道是否有人知道有任何理由喜欢一个而不是另一个?

EDIT: Let me clarify, I'm mostly interested in the cases where it doesn't seem to matter which you choose - that is, is there a performance difference, or any other reason?编辑:让我澄清一下,我最感兴趣的是您选择哪个似乎无关紧要的情况 - 也就是说,是否存在性能差异或任何其他原因? Thanks!谢谢!

typeof is used when you want to get the Type instance representing a specific type. typeof用于获取代表特定类型的Type实例。 GetType gives the runtime type of the object on which it is called, which may be different from the declared type. GetType给出调用它的对象的运行时类型,它可能与声明的类型不同。

For example:例如:

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"
    }
}

In the above case, within the Main method, you're dealing with instances of type A ;在上述情况下,在Main方法中,您正在处理类型A实例; thus, if you care about the declared type, you would use typeof(A) .因此,如果您关心声明的类型,则可以使用typeof(A) However, the CreateA method actually returns an instance of a derived class, B , despite declaring the base class as the return type.但是,尽管将基类声明为返回类型,但CreateA方法实际上返回派生类B的实例。 If you want to find out about this runtime type, call GetType on the returned instance.如果您想了解此运行时类型,请对返回的实例调用GetType

Edit : Mehrdad's comment points in the right direction.编辑:Mehrdad 的评论指向正确的方向。 Although typeof emits a GetTypeFromHandle call that takes a RuntimeTypeHandle as parameter, the said parameter would actually correspond to the specific type whose metadata token is on the evaluation stack.尽管typeof发出一个GetTypeFromHandle调用,该调用将RuntimeTypeHandle作为参数,但该参数实际上对应于元数据标记位于评估堆栈上的特定类型。 In some instances, this token would be there implicitly (due to the current method invocation);在某些情况下,这个标记会隐式存在(由于当前的方法调用); otherwise, it can be pushed there explicitly by calling ldtoken .否则,它可以通过调用ldtoken显式推送到那里。 You can see more examples of this in these answers:你可以在这些答案中看到更多这样的例子:

Edit 2 : If you're looking for performance benchmarks, you can refer to Jon Skeet's answer .编辑2 :如果您正在寻找性能基准,您可以参考Jon Skeet 的回答 His results were (for 100 million iterations):他的结果是(1亿次迭代):

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

Well, sometimes in generic code, you know the compile time type from a type parameter T , without having an instance.好吧,有时在泛型代码中,您可以从类型参数T知道编译时类型,而无需实例。 Then you must use typeof(T) .然后你必须使用typeof(T)

At other times, typically in non generic code, you might be interested in the runtime type of an object.在其他时候,通常在非通用代码中,您可能对对象的运行时类型感兴趣。 Then you use GetType() .然后你使用GetType()

So in some cases, depending on what you want to know, or what you can query for, you only have one option.因此,在某些情况下,根据您想了解的内容或可以查询的内容,您只有一种选择。

And sometimes, you could choose.有时,您可以选择。

You use typeof when you want compile-time information and GetType when you want runtime information.需要编译时信息时使用 typeof,需要运行时信息时使用 GetType。

If you're in a situation where you can use either, you should use typeof because it can be resolved at compile-time.如果您处于可以使用任何一种的情况,则应该使用 typeof,因为它可以在编译时解决。 This makes it clearer what the Type value will be and (in principle) allows more optimizations.这使得 Type 值变得更加清晰,并且(原则上)允许进行更多优化。

The typeof keyword takes a compile-time type identifier and gives you the corresponding runtime instance of 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)

The GetType instance method takes a run-time instance and tells you its exact runtime type: 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()

You typically only need to use typeof or GetType when writing something that does reflection, creating expression trees by hand, or using the terrible Enum methods (which take an instance of Type instead of a generic type parameter).在编写执行反射、手动创建表达式树或使用糟糕的 Enum 方法(采用 Type 的实例而不是泛型类型参数)时,您通常只需要使用 typeof 或 GetType 。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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