【问题标题】:Using inherited types with C# collection generic type parameters使用带有 C# 集合泛型类型参数的继承类型
【发布时间】:2016-03-01 21:46:11
【问题描述】:

我有一个带有几个继承类的抽象类,如下所示:

internal abstract class SomeBaseType {}
internal class FirstSpecificType : SomeBaseType {}
internal class SecondSpecificType : SomeBaseType {}
internal class ThirdSpecificType : SomeBaseType {}

还有一个具有受约束的泛型类型参数的类:

internal class SomeCollection<T> : ICollection<SomeDataStructure>
    where T : SomeBaseType {}

我创建了一个List&lt;SomeCollection&lt;SomeBaseType&gt;&gt; 并尝试添加SomeBaseType 的各种继承类的元素,但出现以下错误(CS1503CS1950):

Argument 1: cannot convert from 'Namespace.SomeCollection<FirstSpecificType>' to 'Namespace.SomeCollection<SomeBaseType>'
The best overloaded Add method 'List<SomeCollection<SomeBaseType>>.Add(SomeCollection<SomeBaseType>)' for the collection initializer has some invalid arguments

既然FirstSpecificTypeSomeBaseType,我应该可以做到,对吧?这与将任意一组object 添加到IList&lt;object&gt; 基本相同。


对于其他上下文,出现此错误的代码如下所示:

protected Constructor()
{
    collectionOne = new SomeCollection<FirstSpecificType>();
    collectionTwo = new SomeCollection<SecondSpecificType>();
    collectionThree = new SomeCollection<ThirdSpecificType>();

    allCollections = new List<SomeCollection<SomeBaseType>>
    {
        // Each of these three collections has the error
        collectionOne,
        collectionTwo,
        collectionThree
    };
}

【问题讨论】:

  • 那是协方差,泛型类的协方差不起作用。
  • 每天都会有人问这个问题。还有一次:长颈鹿的清单不是动物的清单。为什么?因为您可以将老虎放入动物列表,但不能放入长颈鹿列表。动物列表不是长颈鹿列表。为什么?因为动物列表中可能已经有老虎了。因此,长颈鹿列表和动物列表从不兼容,因为您可以对这两种类型执行的操作是不同的。有些动物是长颈鹿这一事实无关紧要。

标签: c# .net generics inheritance


【解决方案1】:

这是covariance and contravariance的问题,基本上是说 FirstSpecificType确实是SomeBaseTypeSomeCollection&lt;FirstSpecificType&gt;严格来说不是SomeCollection&lt;SomeBaseType&gt;

Eric Lippert 写了一些精彩的 articles 关于这个和长颈鹿,我建议大家至少阅读一次 :-)

【讨论】:

  • John Skeet 写了一些很棒的文章... ...为什么不把那篇文章也链接起来呢?
  • @Rahul - 混合 .net 大师的时候,很难找到正确的链接 ;-)
  • 感谢@Amit 的解释和链接。这帮助我找到了实现目标的新方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-29
  • 1970-01-01
  • 2015-11-18
  • 1970-01-01
  • 2018-09-27
相关资源
最近更新 更多