2009-10-19 3 views
1

Как создать производный класс из Hashtable, объекты которого могут быть добавлены, но не могут быть удалены или заменены?Сделать Hashtable неизменным

Что мне нужно переопределить и, в частности, как переопределить оператор []?

+1

Любая причина, почему вы хотите использовать Hashtable вместо общих собраний? –

+0

Единственная причина, по которой у меня нет разумных знаний о доступных коллекциях в C#, поэтому я просто использую Hashtable всякий раз, когда мне нужен string-> object indexer. –

+0

На самом деле, я добавляю два разных типа в Hashtable, поэтому я не использую общие коллекции. –

ответ

3

Как минимум, вы должны переопределить Clear, Remove, имущество Values и индекс Item. Вы можете переопределить индексатор Item, используя синтаксис:

public override this[object key] { 
    get { // get implementation } 
    set { // set implementation } 
} 

Вы должны переопределить Clear, так что пользователь не может очистить хэш-таблицу. Вам необходимо переопределить Remove, чтобы пользователь не смог удалить из хэш-таблицы. Вам необходимо переопределить Values, потому что пользователь может использовать ICollection, который возвращается для изменения значений в хеш-таблице. По этой же причине вам необходимо переопределить Item.

+0

Спасибо. Я только что добавил Add и indexer и использовал композицию вместо наследования. –

+0

Обратите внимание, что это допустимо только при использовании HashTable. Если вы выходите из Словаря, существует, по крайней мере, еще три метода, которые нужно затенять. – Guffa

+0

@HeavyWave: Обратите внимание, что я ответил на ваш вопрос, однако другие проделали выдающуюся работу, объясняя, почему вы не должны этого делать. В частности, вы нарушаете принцип замены Лискова (http://en.wikipedia.org/wiki/Liskov_substitution_principle). (Например, вызов 'Clear', а затем' Count' на 'Hashtable' приведет к нулевому значению, но вызов' Clear', а затем 'Count' на ваш производный класс не будет.) – jason

5

Вместо того чтобы извлекать из Словаря (который вы должны использовать, а не HashTable), вы должны, вероятно, инкапсулировать его в этом случае.

В словаре есть много методов, которые позволяют изменять коллекцию, проще сделать его частным членом, а затем просто реализовать методы для добавления и доступа к элементам.

Что-то вроде:

public class StickyDictionary<Key, Value> : IEnumerable<KeyValuePair<Key, Value>>{ 

    private Dictionary<Key, Value> _colleciton; 

    public StickyDictionary() { 
     _collection = new Dictionary<Key, Value>(); 
    } 

    public void Add(Key key, Value value) { 
     _collection.Add(key, value); 
    } 

    public Value this[Key key] { 
     get { 
     return _collection[key]; 
     } 
    } 

    public IEnumerable<KeyValuePair<Key, Value>> GetEnumerator() { 
     return _collection.GetEnumerator(); 
    } 

} 
+0

Это именно то, что я сделал, спасибо , –

+0

Правильно, вы не должны выводить класс, а затем изменять его поведение по умолчанию (в отличие от его расширения). Если вы это сделаете, пользователи Словаря могут получить версию ImmutableDictionary и потерпеть неудачу из-за того, что он не действует так, как ожидает, что Словарь будет действовать. – noctonura

+0

Нет, мой класс не предназначен для использования в качестве коллекции, а просто хранит множество объектов, доступных несколькими способами. –

Смежные вопросы