泛型类型的奇怪行为

本文关键字:泛型类型 | 更新日期: 2023-09-27 17:56:15

请看下面的简单代码

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:最初的问题有误。现已修复

泛型类型的奇怪行为

想象一下,如果你这样做会发生什么:

public class C : A{}
G<C> x = new G();
C c = x.GetT();

你真的不希望它返回一个B引用......

as运算符工作是因为如果T既不B也不A,它只会返回null......但这可能不是你真正的意思

很难知道要建议的行动方案,而不知道你想做什么。

根据更新重新设计的答案

虽然A满足泛型约束where T : A,但它是一个具体的类型。但是,泛型类的 GetT() 方法具有泛型返回类型 T ,因此您必须将具体类型强制转换为泛型类型以使返回兼容。

旧答案适用于您之前返回new B()的情况。


旧答案

泛型类型约束说T必须继承自A;然而,它并没有T必须B(或它的派生),尽管B碰巧自己继承自A并满足约束。

所以返回类型不兼容(B总是B,但T不一定是B),你得到错误。

相同的代码,只是名称已更改

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"。有一个问题:即使相反,所有的动物都不是鱼。如果需要鱼,则不能归还动物,而不需要任何其他种类的动物。

where T : A表示T必须从A继承。 因此,T可能不是A,所以你不能只返回一个B,因为C也可能是从A继承的,但B不是C