typeof 泛型和强制类型 [重复]
Posted
技术标签:
【中文标题】typeof 泛型和强制类型 [重复]【英文标题】:typeof generic and casted type [duplicate] 【发布时间】:2019-07-16 13:41:30 【问题描述】:假设我们有通用方法:
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
谁能解释一下为什么 typeof 整数转换为对象返回 System.Object,但 .GetType() 返回 System.Int32?
【问题讨论】:
typeof takes
类型名称(您在编译时指定),GetType
获取实例的运行时类型。
另外,如果您发现自己在泛型中进行任何类型的测试,请问问自己是否为这项工作选择了正确的工具。因为这可能意味着您无法在 runtime 正常工作,而您在编译时“承诺”您可以做的事情(通过说您可以为任何类型工作,受该类型的任何泛型类型约束参数)
【参考方案1】:
typeof
返回泛型参数T
的静态(编译时) 类型。
GetType
返回变量item
中包含的值 的动态(运行时) 类型。
如果您将方法设为非泛型,则更容易看出差异。假设B
是A
的子类型:
public void NonGenericMethod(A item)
var typeOf = typeof(A);
var getType = item.GetType();
在这种情况下,调用NonGenericMethod(new B())
会产生
A
B
推荐阅读:
Run-time type vs compile-time type in C#现在,您可能会问:为什么在您的示例中使用 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
。
推荐阅读:
When is the generic type resolved in c#?【讨论】:
虽然typeOf
将在第一次使用特定T
执行函数之前得到解决,但它可能会在程序开始执行之后发生。与 C++ 不同,C# 使程序可以根据输入创建无限数量的不同类型,即使不使用反射也是如此。在这种情况下,可能无法生成可以调用函数的每种类型 T
的列表,因此无法在程序执行之前确定 T
将是什么。【参考方案2】:
在GenericMethod((object) 1)
中,T
将是object
。 typeof 反映了这一点。
但item.GetType();
是一个虚方法,将在运行时在 Int32 上执行。
【讨论】:
【参考方案3】:对 GetType 的调用在运行时被解析,而 typeof 在编译时被解析。 这就是为什么它给出不同的结果。 你可以在这里查看 - When and where to use GetType() or typeof()?
【讨论】:
【参考方案4】:This Tells me Typeof 为您提供编译时间类型,而 GetType 为您提供 Exact Run time 类型。
【讨论】:
【参考方案5】:当你忽略类型干扰时,很多事情都会变得清晰:
GenericMethod(1)
实际上是GenericMethod<int>(1)
。
GenericMethod((object) 1)
被推断为GenericMethod<object>((object) 1)
。
当您询问typeof(T)
时,它会返回您在方法调用中指定的T
。您也可以使用GenericMethod<object>("a")
,这将在typeof(T)
上返回object
。
GetType
返回所提供实例的实际运行时类型。
【讨论】:
以上是关于typeof 泛型和强制类型 [重复]的主要内容,如果未能解决你的问题,请参考以下文章