views:

176

answers:

2

How do I make a derived class from Hashtable, objects of which can be added, but cannot be removed or replaced?

What do I have to override and particularly how do I override the [] operator?

+3  A: 

At a minimum, you should override Clear, Remove, the property Values and the indexer Item. You can override the indexer Item using the syntax:

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

You need to override Clear so that a user can't clear the hashtable. You need to override Remove so that a user can't remove entires from the hashtable. You need to override Values because a user could use the ICollection that is returned to modify the values in the hashtable. You need to override Item for a similar reason.

Jason
Thanks. I've just implemented Add and indexer, and used composition instead of inheritance.
HeavyWave
Note that this is only valid if deriving from HashTable. If you derive from Dictionary there is at least three more methods that you have to shadow.
Guffa
@HeavyWave: Note that I answered your question, however others have done an outstanding job of explaining why you shouldn't do this. In particular, you are violating the Liskov Substitution principle (http://en.wikipedia.org/wiki/Liskov_substitution_principle). (For example, calling `Clear` and then `Count` on a `Hashtable` will produce the value zero, but calling `Clear` and then `Count` on your derived class will not.)
Jason
+5  A: 

Instead of deriving from the Dictionary (which you should use rather than a HashTable), you should probably encapsulate it in this case.

The Dictionary has a lot of methods that allow changing the collection, it's easier to make it a private member, and then just implement the methods to add and access items.

Something like:

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();
   }

}
Guffa
That's exactly what I did, thanks.
HeavyWave
Right, you should not derive a class and then change its default behavior (as opposed to extending it). If you do that, users of Dictionary may get passed a version of the ImmutableDictionary, and fail miserably because its not acting like it expects a Dictionary to act.
RichAmberale
No, my class is not intended to be used as a collection, rather it just stores a lot of objects that are accessible in a few different ways.
HeavyWave
Then it makes good sense to encapsulate the collection instead of deriving from it.
Guffa