避免在基类中使用泛型列表 - 我应该遵循相同的字典规则
本文关键字:我应该 规则 字典 列表 基类 泛型 | 更新日期: 2023-09-27 18:32:50
建议我将基类中的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
.
顺便说一句,Dictionary
的目的是保存错误(格式与ModelState类似(。我目前不确定我将在哪个阶段向其添加错误。
如果我应该避免在基类中使用Dictionary<string, string>
,我应该在它的位置使用什么?
我遇到过KeyedCollection
但不确定这是否是一个很好的替代品。
Dictionary<TKey, TValue>
没有任何基类可以使用它来代替它。使用接口(IDictionary<TKey, TValue>
或IReadOnlyDictionary<TKey, TValue>
- 两者都由Dictionary
实现(可能更好,但这取决于您的需求。
请注意,很难表达属性是返回内部存储还是克隆(因此当调用者更改对象时会发生什么( - 您可能需要考虑隐藏字典作为实现细节的IEnumerable<T>
或方法。
所以基本上你被告知的内容对于你要追求的用例来说可能是错误的。
msdn 文章中的语句表示继承,如果要通过从集合派生来创建自己的集合实现,如下所示:
public class MyCollection : Collection<MyType>
在这种情况下使用 Collection<T>
的优点是,您可以显著更改行为,因为它公开了以下可以重写的方法:ClearItems
、InsertItem
、RemoveItem
和 SetItem
。当你从List<T>
派生时,你根本不能覆盖任何方法(标准ToString
、Equals
和GetHashCode
除外(。
但正如您在评论中所述,您将List
/Dictionary
/Collection
用作属性。因此,这取决于您自己的用例。
如果您希望派生类仅使用基类中的集合,则可以将其设置为您认为最适合您需求的任何内容。但是,如果您认为派生类会更好地了解使用哪个集合,那么您应该从 System.Collections.Generic
命名空间中选择一个接口。
我不会告诉您应该使用哪种类型或接口,因为它在很大程度上取决于您需要的功能。
顺便说一下:KeyedCollection
只能用于创建自己的键值集合(它是抽象的(。因此,将KeyedCollection
作为属性意味着您还需要实现KeyedCollection
。