25

typeof(T) where T : struct有谁知道,例如,与之间的任何区别t.GetType() where t is a System.Object
ILdasm 显示 typeof(T) 使用System.Type::GetTypeFromHandle(RuntimeTypeHandle handle),而另一个只是 plain System.Object::GetType()。实现是[MethodImpl(MethodImplOptions.InternalCall)],因此方法是在 CLR 的本机代码中定义的。所以,我只是想知道是否有人知道有任何理由更喜欢一个而不是另一个?

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

4

4 回答 4

49

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方法中,您正在处理 type 的实例A;因此,如果您关心声明的类型,您将使用typeof(A). 但是,该CreateA方法实际上返回派生类的实例B,尽管将基类声明为返回类型。如果您想了解此运行时类型,请调用GetType返回的实例。

编辑:Mehrdad 的评论指出了正确的方向。尽管typeof发出一个GetTypeFromHandleRuntimeTypeHandleas 参数为参数的调用,但该参数实际上将对应于其元数据令牌在评估堆栈上的特定类型。在某些情况下,此标记会隐式存在(由于当前方法调用);否则,可以通过调用ldtoken将其显式推送到那里。您可以在这些答案中看到更多这样的例子:

编辑2:如果您正在寻找性能基准,您可以参考Jon Skeet 的回答。他的结果是(1亿次迭代):

typeof(Test):   2756ms
test.GetType(): 3734ms
于 2013-07-05T19:08:52.957 回答
4

好吧,有时在泛型代码中,您可以从类型参数中知道编译时类型T,而无需实例。那么你必须使用typeof(T).

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

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

有时,您可以选择。

于 2013-07-05T19:09:28.340 回答
3

需要编译时信息时使用 typeof,需要运行时信息时使用 GetType。

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

typeof 关键字采用编译时类型标识符,并为您提供相应的运行时类型实例:

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 。

于 2013-07-05T19:27:09.433 回答
2

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

于 2013-07-05T19:12:51.700 回答