Strange indexer behavior in user dictionary

I created a custom Dictionary class that inherits from a dictionary. However, strange things happen when calling the indexer, depending on how I use the class. Here's a simplified version of the class:

public class MyDictionary<TKey, TValue> : Dictionary<TKey, TValue> { public new TValue this[TKey key] { get { return base[key]; } set { base[key] = value; } } } 

Now I want to create an instance and add something to it. The following works fine, i.e. I can set a breakpoint in the installer of the indexer and it will be deleted.

 MyDictionary<int, string> dict = new MyDictionary<int, string>(); dict[0] = "some value"; 

However, if I do it like this (create an instance of the IDictionary variable):

 IDictionary<int, string> dict = new MyDictionary<int, string>(); dict[0] = "some value"; 

it will no longer hit my breakpoint in the indexer installer, i.e. it should call something else. If I look at the implementation of the .NET Dictionary (from which my class inherits), I cannot find another indexer other than the one I redefine, and it does not inherit from anything else. So the question is what is going on?

+4
source share
1 answer

The point is in the new key in the indexer declaration. This does not undo the indexer of the base class, and each time you access the indexer from the base class or interface (for example, IDictionary in your example), indexing of the base class will be called. Moreover, you cannot override the base class indexer because it is not marked as virtual in the class definition Dictionary<TKey, TValue>

view this article in the new modifier in the method declaration

Try using composition here instead of inheritance.

If you are sure that you need to customize the behavior exactly for IDictionary<TKey, TValue and no more abstract interfaces, for example ICollection<KeyValuePair<TKey, TValue>> or even IEnumerable<KeyValuePair<TKey, TValue>> , use the following example:

 public class MyDictionary<TKey, TValue> : IDictionary<TKey, TValue> { IDictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>(); //LOTS of other methods here, that are required by IDictionary<TKey, TValue> //their implementation would be delegation to dictionary instance public TValue this[TKey key] //implementation of a interface { get { return dictionary[key]; } set { dictionary[key] = value; } } } 
+10
source

All Articles