Reputation: 2917
I was advised to change a List<string>
property to a Collection<string>
, in a base class, because it is more appropriate for inheritance.
This 'rule' was referred to: https://msdn.microsoft.com/en-us/library/ms182142.aspx
System.Collections.Generic.List is a generic collection that is designed for performance and not inheritance. System.Collections.Generic.List does not contain virtual members that make it easier to change the behavior of an inherited class. The following generic collections are designed for inheritance and should be exposed instead of System.Collections.Generic.List.
System.Collections.ObjectModel.Collection<T> System.Collections.ObjectModel.ReadOnlyCollection<T> System.Collections.ObjectModel.KeyedCollection<TKey, TItem>
Does a similar rule apply to Dictionary<string, string>
?
I ask because it is also in the System.Collections.Generic
namespace. Or maybe I have misunderstood and the rule only applies to Lists
.
BTW, the Dictionary
purpose is to hold errors (in a similar format to ModelState). I am not currently sure at exactly what stage I will be adding errors to it.
If I should be avoiding Dictionary<string, string>
in the base class, what should I be using in it's place?
I have come across KeyedCollection
but not sure if that is a good replacement.
Upvotes: 4
Views: 175
Reputation: 1634
So basically what you were told could potentially be wrong for the use case you are going for.
The statement in the msdn article means by inheritance if you want to create your own implementation of a collection by deriving from it like so:
public class MyCollection : Collection<MyType>
The advantage of using Collection<T>
in this scenario is that you can alter the behavior significantly as it exposes the following methods which can be overriden: ClearItems
, InsertItem
, RemoveItem
and SetItem
. When you derive from List<T>
you can't override any methods at all (except for the standard ToString
, Equals
and GetHashCode
).
But as you stated in your comment you use the List
/Dictionary
/Collection
as a property. Therefore it rather depends on your own use case.
If you want deriving classes to just use the collection from the base class you can let it be whatever you think is best suited for your needs. But if you think that the deriving class will know better which collection to use then you should
pick an interface from the System.Collections.Generic
namespace.
I won't tell you which types or interfaces you should use when as it heavily depends on which functionality you need.
And by the way: the KeyedCollection
can only be used to create your own key value collection (it is abstract). Therefore having a KeyedCollection
as a property would mean that you'd also need an implementaion of a KeyedCollection
.
Upvotes: 2
Reputation: 100547
Dictionary<TKey, TValue>
does not have any base class you can use instead of it. It may be better to use interface (IDictionary<TKey, TValue>
or maybe IReadOnlyDictionary<TKey, TValue>
-both implemented by Dictionary
), but it depends on your needs.
Note that it is very hard to express whether property returns internal storage or clone (and hence what happens when caller changes object) - you may want to consider IEnumerable<T>
or methods that hide dictionary as implementation details.
Upvotes: 4