C#泛型类继承混淆

时间:2018-05-07 13:39:06

标签: c# generics inheritance

abstract class BaseClassA{}

class DerivedClassA : BaseClassA{}

abstract class BaseClassB<T> where T : BaseClassA
{    
  public T foo;
}

class DerivedClassB : BaseClassB<DerivedClassA>
{
  public DerivedClassB(DerivedClassA _foo)
  {
    foo = _foo;
  }
}

class Test
{
  DerivedClassB foobar = new DerivedClassB();
  void main()
  {
    //Error: casting not possible
    BaseClassA<BaseClassB> bar = new DerivedClassA<DerivedClassB>(foobar);
  }
}
嘿大家好 我有一点问题。上面的代码给了我一个“无法投射”的例外。 我希望能够访问DerivedClassB的foo,而无需将其从BaseClassA转换为DerivedClassA。

我不能从基类派生泛型类型并仍然使用它吗?

1 个答案:

答案 0 :(得分:2)

问题在于,如果您想要的是合法的,那么这也是合法的:

abstract class Animal {}
class Goldfish : Animal {}
class Giraffe : Animal {}
abstract class Cage<T> where T : Animal {
   void Add(T newAnimal) { ... }
}
class Aquarium : Cage<Goldfish> { }
...
Cage<Animal> c = new Aquarium(); // This is not legal, but suppose it was
c.Add(new Giraffe()); // A giraffe is an animal

现在我们在水族馆里养了一头长颈鹿,没有人喜欢。

此功能称为协方差,它仅适用于通用接口和委托,当它们使用引用类型构建时,它们是专门设计用于处理差异并由编译器检查安全性

例如,您可以在期望IEnumerable<Fish>的上下文中使用IEnumerable<Animal>,因为无法将长颈鹿添加到动物序列中。

  

我是否有从基类派生的泛型类型并仍在使用它?

是的,但你必须遵守规则。 这些规则可以保证您的安全。了解类型系统如何工作并使用它来帮助防止你的错误,你永远不会错误地将长颈鹿放入水族馆。