C# 通用型和铸造型的类型
假设我们有通用方法:C# 通用型和铸造型的类型,c#,generics,C#,Generics,假设我们有通用方法: public void GenericMethod<T>(T item) { var typeOf = typeof(T); var getType = item.GetType(); } 结果是: typeOf = System.Int32 getType = System.Int32 及 有人能解释为什么强制转换到对象的整数类型返回System.object,而.GetType()返回System.Int32吗?typeof返回泛型参数T
public void GenericMethod<T>(T item)
{
var typeOf = typeof(T);
var getType = item.GetType();
}
结果是:
typeOf = System.Int32
getType = System.Int32
及
有人能解释为什么强制转换到对象的整数类型返回System.object,而.GetType()返回System.Int32吗?
typeof
返回泛型参数T
的静态(编译时)类型
GetType
返回变量项中包含的值的动态(运行时)类型
如果将方法设置为非泛型,则更容易看出区别。让我们假设B
是a
的一个子类型:
public void NonGenericMethod(A item)
{
var typeOf = typeof(A);
var getType = item.GetType();
}
在这种情况下,调用NonGenericMethod(new B())
将产生
A
B
建议进一步阅读:
现在,您可能会问:为什么在示例中使用NonGenericMethod(A项)
,而不是NonGenericMethod(B项)
?这是一个很好的问题!考虑下面的(非泛型)示例代码:
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
类似)时会得到什么
为什么??因为重载解析是在编译时完成的,而不是在运行时。在编译时,表达式(A)new B()
的类型是A
,就像(object)1
的编译时类型是object
建议进一步阅读:
在通用方法((对象)1)
中,T
将是对象
。typeof反映了这一点
但是item.GetType()
是一个虚拟方法,将在运行时在Int32上执行 Typeof提供编译时类型,而GetType提供确切的运行时类型。对GetType的调用在运行时得到解决,而Typeof在编译时得到解决。
这就是为什么它会产生不同的结果。
您可以在此处查看-当您忽略类型干扰时,很多内容都很清楚:
GenericMethod(1)
实际上是GenericMethod(1)
GenericMethod((对象)1)
被推断为GenericMethod((对象)1)
当您询问typeof(T)
时,它返回您在方法调用中指定的T
。您还可以执行GenericMethod(“a”)
,它将在typeof(T)
上返回object
GetType
返回所提供实例的实际运行时类型。typeof获取类型名称(您在编译时指定),GetType
获取实例的运行时类型。此外,如果您发现自己在泛型中执行任何类型的类型测试,问问自己,你是否为这份工作选择了合适的工具。因为这可能意味着您无法在运行时正常工作—您在编译时“承诺”可以做的事情(通过说您可以为任何类型工作,受该类型参数上的任何泛型类型约束),尽管typeOf
将在第一次使用特定T
执行函数之前得到解决,它可能发生在程序开始执行之后。与C++不同,C语言使得程序可以根据输入创建无限数量的不同类型,甚至不用反射。在这种情况下,可能不可能生成调用函数的每种类型的T
列表,因此不可能确定在程序执行之前是什么类型的T
。
A
B
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();
}
Method A
A
B