[英]Why can't I cast int to T, but can cast int to object and then object to T?
This code does not compile: 此代码无法编译:
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;
}
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. 我不明白为什么编译器可以将一个对象(实际类型可以是任何东西)转换为T,却不能将一个int(对象的隐式继承)转换为T。
As SLaks says, the compiler knows that T
is convertible to object but that's only half of it. 正如SLaks所说,编译器知道T
可转换为对象,但这只是其中的一半。 The compiler also knows that any object of type T
derives from object
, so it needs to allow downcast from object
to T
. 编译器还知道,任何类型T
对象都是从object
派生的,因此它需要允许从object
向下转换为T
Collections pre v2.0 needed this. v2.0之前的收藏需要此。 Not to T
of course but to be able to downcast from object to any type. 当然不是要T
,而是要从对象向下转换为任何类型。 It would have been impossible to get anything out of a collection as anything else than an object. 除了对象之外,从集合中获取任何东西都是不可能的。
The same is not true when talking about T
and int
. 在谈论T
和int
时,情况并非如此。 Your code is of course safe from those problems at runtime due to the if statement, but the compiler can't see that. 由于if语句,您的代码在运行时当然可以避免那些问题,但是编译器看不到。 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 通常(但不是在这种情况下)证明,如果在某些外部条件为真的情况下,您将永远无法进入NP主体,因为NP完全,并且由于我们希望编译器在某个时候完成,所以不会尝试并基本解决千年奖金问题
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. 如果您不能用特定类型的T
替换非通用代码,那么它不仅在这种情况下,而且通常是无效的。 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. 如果您知道该方法的所有用例实际上都是有效的,则可以对通用方法使用约束 。
The compiler doesn't know that T
is int
. 编译器不知道T
是int
。 (even though you just proved that it is int
in your if
) (即使您只是证明了if
为int
)
By contrast, the compiler does know that T
is always convertible to object
. 相反,编译器确实知道T
始终可转换为object
。
For example, if T
is string
, it's still convertible to object
, but it's not convertible to int
. 例如,如果T
为string
,则它仍然可以转换为object
,但不能转换为int
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.