我正在尝试创建一个每个类型只包含一个元素的集合。然而,每种类型都必须子类化根类型,因此存在共性。 我做了一些研究,我想知道我是否走在正确的轨道上,或者是否有一些改进:
class TypedList<T> : Dictionary<Type, T> {
public override void Add<C>(T instanceOfType) {
base.Add(typeof(C), instanceOfType);
}
}
具体问题:
更新了代码以反映Ondrej的建议:
class TypedList<Abstract> : IList<Abstract> {
protected Dictionary<Type, Abstract> data;
public void TypedList() {
data = new Dictionary<Type, Abstract>();
}
public void Add<Concrete>(Concrete instanceOfType) where Concrete : Abstract {
data.Add(typeof(Concrete), instanceOfType);
}
}
答案 0 :(得分:0)
这种方法通常看起来很好。但是,我会考虑将Dictionary<Type, T>
隐藏为私有字段并重新实现所需的接口。它不必是IDictionary<Type, T>
,也可能只是IList<T>
。
另一种选择是使用List<T>
进行内部存储,使用HashSet<Type>
来维护列表中的项目类型集。如果IList<T>
是TypedList<T>
的有用接口,用字典解决“缺失索引”问题,这样的底层存储可能更适合。
此外,Add<C>
方法声明似乎不正确。你应该声明为:
public override void Add<C>(C instanceOfType) where C : T {
base.Add(typeof(C), instanceOfType);
}
确保C
成为T
的祖先。在原始声明中C
可以是任何类型,可能与T
无关。
答案 1 :(得分:0)
这应该会给你你正在寻找的约束!
class TypedList:Dictionary {
public override void Add<C>(T instanceOfType) where C : T{
base.Add(typeof(C), instanceOfType);
}
}
然而,我想知道你为什么不直接使用字典? I.E.你正在进行子类化的字典应该按照你想要的方式运行吗?
答案 2 :(得分:0)
几个月后,我想我已经提出了一个非常好的解决方案,即使用我最初不知道的集合KeyedCollection
:
public class TypedSet<AbstractType> : KeyedCollection<Type, AbstractType> {
protected override Type GetKeyForItem(AbstractType item) {
return item.GetType();
}
}
非常苛刻,并且不需要将不同类型的集合类拼接在一起。使用稍微更惯用的代码以及KeyedCollection
是抽象的,需要实现GetKeyForItem
。