【发布时间】:2016-07-28 07:40:35
【问题描述】:
考虑如下所示的类层次结构。本质上,有一个抽象的ComplexBase,其中包含所有类共有的一些字段。然后有一个派生自ComplexBase 的ComplexClass,其中包含同样派生自ComplexBase 的ComplexElements 的集合。
public abstract class ComplexBase {
internal abstract string Identifier { get; }
}
public abstract class ComplexClass<T> : ComplexBase where T : ComplexElement {
internal SortedList<string, T> Elements { get; set; }
}
public abstract class ComplexElement : ComplexBase { }
抽象类的实现是ComplexClassA 和ComplexClassB。前者的ComplexElement 集合仅包含ComplexElementA 的实例,而后者仅包含ComplexElementB 的实例。
public class ComplexClassA : ComplexClass<ComplexElementA> {
public ComplexClassA() {
Elements = new SortedList<string, ComplexElementA>();
}
}
public class ComplexElementA : ComplexElement { }
public class ComplexClassB : ComplexClass<ComplexElementB> {
public ComplexClassB() {
Elements = new SortedList<string, ComplexElementB>();
}
}
public class ComplexElementB : ComplexElement { }
我很难理解的是如何定义一个新类TheBigCollection 包含各种字段和方法,以及ComplexClassA 和ComplexClassB 的实例集合。非工作版本可能看起来像
public class TheBigCollection {
internal SortedList<string, ComplexClass> Classes { get; set; }
public TheBigCollection() {
Classes = new SortedList<string, ComplexClass>();
}
public void Add(string name, ComplexClass element) {
Classes.Add(name, element);
}
}
当然这不会编译,因为ComplexClass 是用泛型类型定义的。
我的previous attempt 是使用隐藏列表的概念,但事实证明,这会阻止我在我从列表中检索到的ComplexClassA 或ComplexClassB 的实例中访问ComplexElements 的列表TheBigCollection.
我从之前的帖子中了解到协方差可以解决问题,但我不明白如何使用 IEnumerable(它是不可变的)来向 TheBigCollection 的类列表添加新元素。
【问题讨论】:
-
您是否考虑过创建一个中间类 ComplexClassBase : ComplexBase 并从 ComplexClassBase 继承 ComplexClass
? -
@michauzo 是的,我做到了,非常符合this post 的答案。此解决方案出现的问题是,如果没有适当的演员表,我将无法遍历列表
Classes并访问每个项目的Elements.Count属性。 -
在中间类(或接口)中,您可以将属性 SortedList
Elements { get;放; } 然后使用专门的类型在 ComplexClass 中实现它。 -
不幸的是,这意味着对于
ComplexClass的任何实现,中间类中的Elements将是null。专用类型将隐藏更通用的属性SortedList<string, ComplexElement>,并且TheBigCollection的Classes列表中的任何项目将显示Elements为null。
标签: c# list generics covariance