启动列表<;ChildClass>;进入列表<;ParentClass>;

本文关键字:gt lt 列表 ParentClass ChildClass 启动 | 更新日期: 2023-09-27 18:29:23

我很难找到这个问题的正确单词,所以我会用一些代码向你展示我的问题是什么。

我有一个父类,看起来像这样:

public class ParentClass {
    public Guid ParentId { get; }
    public int ParentProperty { get; set; }
    public List<ParentClass> ParentList { get; set; }
    public ParentClass() {
        this.ParentId = Guid.NewGuid();
    }
}

它相当简单:它有一个ID、几个属性和一个包含其自身元素的List。

现在我正在创建一个子类,它看起来像这样:

public class ChildClass : ParentClass {
    public string ChildProperty { get; set; }
    public ChildClass() : base() {
        this.ParentList = new List<ChildClass>();
    }
}

这个有一个额外的属性和一个构造函数,其中包含了这个问题。我无法将List初始化到List的声明中。我不能只在子类中声明列表,因为当我使用它时,我需要在父类中声明它

解决这个问题的最佳方法是什么?

启动列表<;ChildClass>;进入列表<;ParentClass>;

您应该使用指向两个类(ParentClassChildClass)的接口。

具有特定类型参数的泛型类型是"新"类型:因此List<ChildClass>List<ParentClass>是不同的类型。

我认为实现您想要的最简单的方法是启动具有基本类型的列表:List<ParentClass>

public class ChildClass : ParentClass
{
    public string ChildProperty { get; set; }
    public ChildClass() : base() {
        this.ParentList = new List<ParentClass>();
    }
    public void AddSomething()
    {
        // this is ok :
        this.ParentList.Add(new ChildClass());
    }
}

只有当类型List<T>T(也称为"out T")中协变时,这才能工作。然而,它不是,也不可能是。

  • 类型List<>允许AddInsert和其他类型,因此它在语义上不是协变的
  • 在C#中(截至目前),class类型不能变为协变类型。这是不受支持的。只有interfacedelegate类型的泛型参数可以变为协变(或逆变)

我们得到的最接近的是IReadOnlyList<out T>,它是协变的,所以:

IReadOnlyList<ParentClass> parentList = new List<ChildClass>();

是允许的。但是,这对的情况没有帮助。

 public class ParentClass<TChild>  where TChild : class
    {
        public List<TChild> ParentList { get; set; }
        public Guid ParentId { get; set; }
        public int ParentProperty { get; set; }

        public ParentClass()
        {
            ParentId = Guid.NewGuid();
            ParentList = new List<TChild>();
        }
    }
    public class ChildClass : ParentClass<ChildClass>
    {
        public string ChildProperty { get; set; }
    }