泛型类型的奇怪行为

时间:2011-05-13 11:01:30

标签: c# generics

请查看下面的简单代码

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:初始问题出错。现在修好了

4 个答案:

答案 0 :(得分:6)

想象一下如果你做了会发生什么:

public class C : A{}

G<C> x = new G();
C c = x.GetT();

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

as运算符有效,因为如果null不是TB,它只会返回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