如何创建一个强类型集合,每个类型只包含一个元素

时间:2014-01-03 15:28:59

标签: c# collections strong-typing

我正在尝试创建一个每个类型只包含一个元素的集合。然而,每种类型都必须子类化根类型,因此存在共性。 我做了一些研究,我想知道我是否走在正确的轨道上,或者是否有一些改进:

class TypedList<T> : Dictionary<Type, T> {

    public override void Add<C>(T instanceOfType) {
        base.Add(typeof(C), instanceOfType);
    }

}

具体问题:

  • 这是正确/最好的方法吗?
  • 我应该怎么做以方便检索元素?
  • 如果Add()方法是正确的,有没有办法强制C是T的子类?

更新了代码以反映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);
    }

} 

3 个答案:

答案 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