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

时间:2013-07-05 19:05:28

标签: c# .net

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

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

4 个答案:

答案 0 :(得分:44)

如果要获取表示特定类型的typeof实例,则使用

TypeGetType给出了调用它的对象的运行时类型,它可能与声明的类型不同。

例如:

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's answer。他的结果是:

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

答案 1 :(得分:4)

好吧,有时候在通用代码中,你知道类型参数T的编译时类型,而没有实例。然后,您必须使用typeof(T)

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

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

有时候,你可以选择。

答案 2 :(得分:3)

如果需要编译时信息,可以使用typeof;当需要运行时信息时,可以使用GetType。

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

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。

答案 3 :(得分:2)

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