避免基类中的通用列表 - 我应该遵循相同的字典规则吗?

时间:2016-02-01 00:05:01

标签: c# list generics inheritance dictionary

我是advised在基类中将List<string>属性更改为Collection<string>,因为它更适合继承。

此“规则”被称为:https://msdn.microsoft.com/en-us/library/ms182142.aspx

  

System.Collections.Generic.List是一个通用集合   专为性能而非继承而设计。   System.Collections.Generic.List不包含虚拟成员   这样可以更容易地更改继承类的行为。该   以下泛型集合是为继承而设计的   暴露而不是System.Collections.Generic.List。

System.Collections.ObjectModel.Collection<T>

System.Collections.ObjectModel.ReadOnlyCollection<T>

System.Collections.ObjectModel.KeyedCollection<TKey, TItem>

类似的规则是否适用于Dictionary<string, string>

我问,因为它也在System.Collections.Generic命名空间中。或者我可能误解了,该规则仅适用于Lists

BTW,Dictionary目的是保存错误(与ModelState的格式类似)。我目前还不确定我将在哪个阶段添加错误。

如果我 在基类中避免使用Dictionary<string, string>,我应该在其中使用什么?

我遇到了KeyedCollection,但不确定这是否是一个很好的替代品。

2 个答案:

答案 0 :(得分:4)

Dictionary<TKey, TValue>没有任何可以使用的基类而不是它。最好使用接口(IDictionary<TKey, TValue>IReadOnlyDictionary<TKey, TValue> - 由Dictionary实现 - 但这取决于您的需求。

请注意,很难表达属性是返回内部存储还是克隆(因此当调用者更改对象时会发生什么) - 您可能需要考虑IEnumerable<T>或隐藏字典作为实现细节的方法。

答案 1 :(得分:2)

所以基本上你被告知可能对你正在使用的用例有误。

msdn文章中的语句意味着继承如果你想通过如下派生来创建你自己的集合实现:

public class MyCollection : Collection<MyType>

在此方案中使用Collection<T>的优点是,您可以显着改变行为,因为它公开了以下可以覆盖的方法:ClearItemsInsertItem,{{1} }和RemoveItem。当您从SetItem派生时,您根本无法覆盖任何方法(标准List<T>ToStringEquals除外)。

但正如您在评论中所述,您使用GetHashCode / List / Dictionary作为财产。因此,它取决于您自己的用例。

如果您希望派生类只使用基类中的集合,您可以将它放在您认为最适合您需求的任何内容中。但是如果你认为派生类会更好地知道要使用哪个集合,那么你应该这样做 从Collection命名空间中选择一个接口。

我不会告诉您应该使用哪种类型或接口,因为它在很大程度上取决于您需要哪种功能。

顺便说一句:System.Collections.Generic只能用于创建自己的键值集合(它是抽象的)。因此,将KeyedCollection作为属性意味着您还需要实现KeyedCollection