4

I have a complex data container with multiple levels of nested Dictionaries.

But having Key and Value properties make it non-intuitive and hard to use.

Please suggest the simplest way to rename Key and Value properties in Dictionary<,> subclasses.

Update:

Patryk Ćwiek: If you implement IDictionary<TKey, TValue>, you also can't rename properties, because they're part of the contract.

You're right. My question was not correct. Usage of KeyValuePair in IDictionary restrict the pair properties to Key and Value. So if we want non Key/Value pair we had to implement IDictionary with custom KeyValuePair struct. Or may be there is some other tricky way?

PS. Maybe someone suggest an IDictionary code generation template?

DIF
  • 2,470
  • 6
  • 35
  • 49
Igor
  • 310
  • 1
  • 14
  • 2
    If it's a subclass, then you can't. If you implement `IDictionary`, you also can't rename properties, because they're part of the contract. What you probably could do is composition instead of inheritance. – Patryk Ćwiek Jan 24 '14 at 08:43
  • 2
    *I have complex data container with multiple levels of nested Dictionaries.* If you're nesting them purely to have a composite key then make a `struct MyKey { string x; int y; }` but make them properties. Do the gethashcode/equality stuff. Now you don't have nested dictionaries. – ta.speot.is Jan 24 '14 at 08:49
  • @PatrykĆwiek You could always do explicit interface implementation to "hide" some of the members you need to implement. – ta.speot.is Jan 24 '14 at 08:59
  • @ta.speot.is That's true. But in OP's case, it seems like he would like to break the dictionary contract, which might hint that his data structure neither should *be* nor *behave* like a `Dictionary<_,_>`/`IDictionary<_,_>`, and couldn't be substituted for one. – Patryk Ćwiek Jan 24 '14 at 09:04
  • 1
    I agree with all the above comments, but I do disagree with the original OP who says that Key/Value property names for a Dictionary are 'non-intuitive'. If a Dictionary didn't have those properties I be slightly confused! I wonder what he wants to replace them with? – simon at rcl Jan 24 '14 at 09:16
  • So you problem is that you get expressions like `.Value.Value.Key` and similar? Do you want to make some extension methods to `KeyValuePair>` so you can say `.Meaningful()` instead of `.Key`, etc.? Not sure your question is clear. – Jeppe Stig Nielsen Jan 26 '15 at 08:49

1 Answers1

4

Make your own interface with the property name(s) you want. Then, have your concrete class implement your custom interface.

To keep your code DRY, create a private Dictionary that you delegate all of your work to. You can even have your custom interface be Enumerable (or anything else that IDictionary implements) by delegating the required methods to your private variable.

Here is an example. You would just need change your code from using IDictionary to IComplexDataContainer.

  interface IComplexDataContainer<TKey, TValue>
    : IEnumerable<KeyValuePair<TKey,TValue>>
  {
    TValue this[TKey index] { get; set; }
  }

  class MyComplexDataContainer<TKey, TValue>
    : IComplexDataContainer<TKey, TValue>
  {
    IDictionary<TKey, TValue> hiddenHelper { get; set; }

    public MyComplexDataContainer()
    {
      hiddenHelper = new Dictionary<TKey, TValue>();
    }

    // delegate all of the work to the hidden dictionary
    public TValue this[TKey index]
    {
      get
      {
        return hiddenHelper[index];
      }
      set
      {
        hiddenHelper[index] = value;
      }
    }

    // Just delegate the IEnumerable interface to your hidden dictionary
    // or any other interface you want your class to implement
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
      return hiddenHelper.GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
      return GetEnumerator();
    }
  }

Then you would just use like this:

  IComplexDataContainer<string, int> myData = new MyComplexDataContainer<string,int>();
  myData["tom"] = 18;
  myData["dick"] = 22;
  myData["harry"] = myData["tom"];
Matt Klein
  • 7,856
  • 6
  • 45
  • 46
  • Thanks for your answer. Problem is KeyValuePair that constrain Key and Value properties, which i want to rename. – Igor Jan 27 '14 at 05:52