c#通用列表子类型操作不起作用

c#通用列表子类型操作不起作用,c#,generics,subtyping,C#,Generics,Subtyping,我有一个子类型列表: public class LDBList<T> : List<T> where T : LDBRootClass { ... 公共类LDBList:列表 其中T:LDBRootClass{。。。 我需要把他们干掉 LDBList<TSHeaderItem> catted = tsh1.Concat2(tsh2); LDBList catted=tsh1.Concat2(tsh2); (而TSHeaderItem确实是LD

我有一个子类型列表:

public class LDBList<T> : List<T> 
    where T : LDBRootClass { ...
公共类LDBList:列表
其中T:LDBRootClass{。。。
我需要把他们干掉

LDBList<TSHeaderItem> catted = tsh1.Concat2(tsh2);
LDBList catted=tsh1.Concat2(tsh2);
(而TSHeaderItem确实是LDBRootClass的一个子类型)

我明白了

错误CS0266无法隐式转换类型 “System.Collections.Generic.IEnumerable”到 “LDB.LDBList”。存在显式转换(是 你错过了一个演员吗?)

提供的cast只是将错误从编译时推送到运行时

现在我可以看到发生了什么,好吧,但我不知道如何修复它。所以

  • 我在这里具体做什么,以及

  • 更重要的是,我显然对c#泛型了解不够,因此无法获得关于如何解决这类问题的基本知识,我从哪里开始阅读


  • 谢谢!

    忽略从
    列表继承几乎不可取的事实,您可以创建一个副本构造函数:

    public class LDBList<T> : List<T> where T : LDBRootClass
    {
        public LDBList(IEnumerable<T> collection) : base(collection) { }
    }
    
    公共类LDBList:列表,其中T:LDBRootClass
    {
    公共LDBList(IEnumerable集合):基(集合){}
    }
    
    这将允许您执行以下操作:

    var catted = new LDBList<TSHeaderItem>(tsh1.Concat2(tsh2));
    
    var catted=新的LDBList(tsh1.Concat2(tsh2));
    
    至于你的第二个问题,这实际上与泛型无关,而是与一般的类型系统有关

    tsh1.Concat2(tsh2)
    返回
    IEnumerable
    ,而不是
    LDBList
    ,因此您需要做一些事情将
    IEnumerable
    转换为
    LDBList


    虽然
    LDBList
    实现了
    IEnumerable
    ,但并非所有的
    IEnumerable
    s都是
    LDBList
    s,实际上在这种情况下是
    tsh1.Concat2(tsh2)的运行时类型
    将是
    ConcatIterator

    忽略从
    列表继承几乎从来都不可取的事实,您可以创建一个副本构造函数:

    public class LDBList<T> : List<T> where T : LDBRootClass
    {
        public LDBList(IEnumerable<T> collection) : base(collection) { }
    }
    
    公共类LDBList:列表,其中T:LDBRootClass
    {
    公共LDBList(IEnumerable集合):基(集合){}
    }
    
    这将允许您执行以下操作:

    var catted = new LDBList<TSHeaderItem>(tsh1.Concat2(tsh2));
    
    var catted=新的LDBList(tsh1.Concat2(tsh2));
    
    至于你的第二个问题,这实际上与泛型无关,而是与一般的类型系统有关

    tsh1.Concat2(tsh2)
    返回
    IEnumerable
    ,而不是
    LDBList
    ,因此您需要做一些事情将
    IEnumerable
    转换为
    LDBList


    虽然
    LDBList
    实现了
    IEnumerable
    ,但并非所有的
    IEnumerable
    s都是
    LDBList
    s,实际上在这种情况下是
    tsh1.Concat2(tsh2)的运行时类型
    将是
    ConcatIterator

    谢谢,我会尝试!为什么不希望从列表中继承?如果您推荐的话,我很乐意封装而不是继承。我也理解正在发生的事情,但是“…所以您需要做些事情来转换…”关键是——我从哪里开始阅读以减少主题的n00b;能够解决这些问题?从
    列表继承的优点已经讨论了很多次;这里有一个这样的讨论:。至于转换类型,每个场景都有自己的特定解决方案,因此没有真正的一般阅读领域。幸运的是
    List
    的作者意识到从
    IEnumerable
    创建列表是一项常见的要求,他们提供了一个“复制构造函数”“为什么不继承”主要是讨论is-a和has-a。我对列表的使用原则上是is-a,所以是继承的,如果我发现这是一个错误,我可以很容易地切换到封装。谢谢,我会尝试!为什么不希望从列表继承?如果你推荐的话,很高兴封装而不是继承。a我也明白发生了什么,但是“…所以你需要做点什么来转换…”关键是——我从哪里开始阅读以减少主题的n00b;能够解决这些问题?从
    列表继承的优点已经讨论了很多次;这里有一个这样的讨论:。至于转换类型,每个场景都有自己的特定解决方案,因此没有真正的一般阅读领域。幸运的是
    List
    的作者意识到从
    IEnumerable
    创建列表是一项常见的要求,他们提供了一个“复制构造函数”“为什么不继承”主要是讨论is-a和has-a。我对list的使用原则上是is-a,所以是继承的,如果我发现这是一个错误,我可以很容易地转到封装。