关于c#:typeof generic和casted类型

typeof generic and casted type

本问题已经有最佳答案,请猛点这里访问。

假设我们有通用方法:

1
2
3
4
5
public void GenericMethod<T>(T item)
{
    var typeOf = typeof(T);
    var getType = item.GetType();
}

我们用以下参数调用它:

1
2
GenericMethod(1)
GenericMethod((object) 1)

结果是:

1
2
typeOf = System.Int32
getType = System.Int32

1
2
typeOf = System.Object
getType = System.Int32

有人能解释一下为什么类型化为object的integer返回System.Object,而.getType()返回System.Int32吗?


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

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

如果您将方法设置为非泛型,则很容易看到不同之处。假设BA的一个子类型:

1
2
3
4
5
public void NonGenericMethod(A item)
{
    var typeOf = typeof(A);
    var getType = item.GetType();
}

在这种情况下,打电话给NonGenericMethod(new B())将产生

1
2
A
B

建议进一步阅读:

  • C中的运行时类型与编译时类型#

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

1
2
3
4
5
6
7
8
9
10
11
12
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),你会得到什么?

1
2
3
Method A
A
B

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

建议进一步阅读:

  • C中的泛型类型何时解析?


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

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


对gettype的调用在运行时得到解析,而typeof在编译时得到解析。这就是它产生不同结果的原因。您可以检查这里-何时何地使用getType()或typeof()?


在排除类型干扰时,可以清楚地看到:

GenericMethod(1)实际上是GenericMethod(1)

GenericMethod((object) 1)推断为GenericMethod((object) 1)。

当您询问typeof(T)时,它返回您在方法调用中指定的T。你也可以做GenericMethod("a"),它会把object返回到typeof(T)上。

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


这告诉我typeof为您提供编译时类型,而gettype为您提供确切的运行时类型。