泛型和强制类型的类型

时间:2019-02-22 12:44:57

标签: c# generics

假设我们有通用方法:

public void GenericMethod<T>(T item)
{
    var typeOf = typeof(T);
    var getType = item.GetType();
}

我们正在使用以下参数调用它:

GenericMethod(1)
GenericMethod((object) 1)

结果是:

typeOf = System.Int32
getType = System.Int32

typeOf = System.Object
getType = System.Int32

有人可以解释一下为什么强制转换为object的typeof整数返回System.Object,但是.GetType()返回System.Int32吗?

5 个答案:

答案 0 :(得分:30)

typeof返回通用参数T静态(编译时)类型。

GetType返回变量item中包含的动态(运行时)类型。


如果您将方法设为非泛型,则更容易看出差异。假设BA的子类型:

public void NonGenericMethod(A item)
{
    var typeOf = typeof(A);
    var getType = item.GetType();
}

在这种情况下,调用NonGenericMethod(new B())会产生

A
B

建议进一步阅读:


现在,您可能会问:为什么在示例中使用NonGenericMethod(A item)而不是NonGenericMethod(B item)这是一个很好的问题!考虑以下(非通用)示例代码:

public static void NonGenericMethod(A item)
{
    Console.WriteLine("Method A");
    var typeOf = typeof(A);
    var getType = item.GetType();
}
public static void NonGenericMethod(B item)
{
    Console.WriteLine("Method B");
    var typeOf = typeof(B);
    var getType = item.GetType();
}

调用NonGenericMethod((A) new B())(与示例中的参数(object) 1类似)会得到什么?

Method A
A
B

为什么?因为重载解析是在编译时而不是在运行时完成的。在编译时,表达式(A) new B()的类型为A,就像(object) 1的编译时类型为object。< / p>

建议进一步阅读:

答案 1 :(得分:2)

GenericMethod((object) 1)中,T将是object。 typeof反映了这一点。

但是item.GetType();是一个虚拟方法,将在Int32上的运行时执行。

答案 2 :(得分:1)

对GetType的调用在运行时解析,而typeof在编译时解析。 这就是为什么它给出不同结果的原因。 您可以在这里查看-When and where to use GetType() or typeof()?

答案 3 :(得分:0)

This Tells me Typeof提供了编译时间类型,而GetType提供了精确运行时类型。

答案 4 :(得分:0)

当您排除类型干扰时,很多事情会变得很清楚:

GenericMethod(1)实际上是GenericMethod<int>(1)

GenericMethod((object) 1)被推断为GenericMethod<object>((object) 1)

当您询问typeof(T)时,它将返回您在方法调用中指定的T。您还可以执行GenericMethod<object>("a"),它将在object上返回typeof(T)

GetType返回所提供实例的实际运行时类型。