Есть две проблемы, которые вы должны рассмотреть, обе из которых предполагают, что это плохая идея.
Во-первых, наследование от типов коллекций .NET BCL обычно не является хорошей идеей.Основная причина этого заключается в том, что большинство методов этих типов (например, Add
и Remove
) не являются виртуальными - и если вы предоставите свои собственные реализации в производном классе, они не будут вызваны, если вы передадите свою коллекцию какбазовый тип.В вашем случае, скрывая свойство индексатора Dictionary<TK,TV>
, вы создаете ситуацию, когда вызов с использованием ссылки на базовый класс будет делать что-то отличное от вызова с использованием ссылки на производный класс ... нарушение Принцип подстановки Лискова :
var derived = new D();
var firstItem = derived["puppy"]; // adds the puppy entry
var base = (Dictionary<string,I>)derived;
var secondItem = base["kitten"]; // kitten WAS NOT added .. BAD!
Во-вторых, и что еще более важно , создание индексатора, который вставляет элемент при попытке найти один , совершенно неожиданно ,Индексаторы четко определили операции get
и set
- реализация операции get
для изменения коллекции очень плоха.
Для описанного вами случая вам гораздо лучше создать метод расширения, которыйможет работать с любым словарем.Такая операция менее удивительна в том, что она делает, и также не требует создания производного типа коллекции:
public static class DictionaryExtensions
{
public static TValue FindOrAdd<TKey,TValue>(
this IDictionary<TKey,TValue> dictionary, TKey key, TValue value )
where TValue : new()
{
TValue value;
if (!this.TryGetValue(key, out value))
{
value = new TValue();
this.Add(key, value);
}
return value;
}
}