请查看下面的简单代码
public class A{}
public class B: A{}
public class G<T> where T : A
{
public T GetT()
{
return new A();
}
}
此代码不正确 - 编译器错误“无法将A转换为返回类型T”。 但A实际上是T.如果我改变了
return new A();
到
return new A() as T;
一切都好。这种行为的原因是什么?
提前致谢
UPD:初始问题出错。现在修好了
答案 0 :(得分:6)
想象一下如果你做了会发生什么:
public class C : A{}
G<C> x = new G();
C c = x.GetT();
你真的不希望它返回B
引用...
as
运算符有效,因为如果null
不是T
或B
,它只会返回A
...但这可能是不是真的你的意思。
在不知道你想要做什么的情况下,很难知道建议的行动方案。
答案 1 :(得分:5)
根据更新重新编写的答案
虽然A
符合通用约束where T : A
,但它是一种具体类型。但是,您的泛型类的GetT()
方法具有通用返回类型T
,因此您必须将具体类型转换为泛型类型以使返回兼容。
旧答案适用于您之前返回new B()
的情况。
旧答案
泛型类型约束表明T
必须从A
继承;但是,不表示T
必须是B
(或其衍生物),尽管B
恰好从A
继承而来并满足约束。
因此返回类型不兼容(B
始终为B
,但T
不一定是B
),您会收到错误。
答案 2 :(得分:1)
相同的代码,只是名称已更改
public class Animal{}
public class G<T> where T : Animal
{
public T GetT()
{
return new Animal();
}
}
Fish fish = new G<Fish>().GetT();
但是GetT()没有返回Fish,它返回一个匿名的“Animal”。有一个问题:即使相反,所有动物都不是鱼。如果需要鱼,你不能返回动物,而不是任何其他动物。
答案 3 :(得分:0)
where T : A
表示T必须从A继承。因此,T
可能不是A
,因此您不能只返回B
,{{1也可以从C
继承,但A
不是B
。