问题描述
这段代码无法编译:
public T Get<T>()
{
T result = default(T);
if(typeof(T) == typeof(int))
{
int i = 0;
result = (T)i;
}
return result;
}
但是,此代码确实可以编译:
however, this code does compile:
public T Get<T>()
{
T result = default(T);
if(typeof(T) == typeof(int))
{
int i = 0;
result = (T)(object)i;
}
return result;
}
代码也可以正常工作.我不明白为什么编译器可以将对象(实际类型可以是任何东西)转换为 T,但不能将 int(从对象继承)转换为 T.
The code also works fine. I don't understand why the compiler can cast an object (actual type could be anything) to T, but cannot cast an int (which inherets from object) to T.
推荐答案
正如 SLaks 所说,编译器知道 T
可以转换为对象,但这只是它的一半.编译器也知道任何 T
类型的对象都从 object
派生,所以它需要允许从 object
向下转换到 T代码>.v2.0 之前的集合需要这个.当然不是
T
而是能够从对象向下转换为任何类型.从集合中取出任何东西作为对象是不可能的.
As SLaks says, the compiler knows that T
is convertible to object but that's only half of it. The compiler also knows that any object of type T
derives from object
, so it needs to allow downcast from object
to T
. Collections pre v2.0 needed this. Not to T
of course but to be able to downcast from object to any type. It would have been impossible to get anything out of a collection as anything else than an object.
当谈论T
和int
时,情况并非如此.由于 if 语句,您的代码在运行时当然不会出现这些问题,但编译器看不到这一点.一般来说(但不是在这种情况下)证明在某些外部条件为真的情况下您永远不会到达 if 的主体是 NP-complete 并且由于我们希望编译器在某个时候完成,因此它不会尝试基本上解决 千年奖问题
The same is not true when talking about T
and int
. Your code is of course safe from those problems at runtime due to the if statement, but the compiler can't see that. In general (not in this case though) proving that you will never get to the body of an if in the case of some external condition being true is NP-complete and since we wish the compiler to complete at some point, it's not going to try and basically solve a millennium prize problem
在许多情况下,在非通用代码中不允许用特定类型替换 T
.
There are many scenarios where substituting a specific type for T
would not be allowed in non-generic code.
如果您不能将代码编写为使用特定类型替换 T
的非通用代码,则它无效,不仅在这种情况下,而且在一般情况下都是如此.如果您知道该方法的所有用例实际上都是有效的,您可以使用 约束 到您的通用方法.
If you can't write the code as non-generic for any substitution of T
with a specific type, it's not valid, not just in this case but generally. If you know that for all your use cases of the method it would actually be valid, you can use constraints to your generic method.
这篇关于为什么我不能将 int 转换为 T,但可以将 int 转换为 object,然后再将 object 转换为 T?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!