user4583300
user4583300

Reputation:

"More functional" "accessor" for collections in C#

Now I have a collection: Dictionary<string, List<string>> dictionary.

For some reason, now I want to "project/map" a part of it to other collections, sort of like using it as backing field, and create different accessors for this collection.

Like List<string> keys corresponds to the keys of this dictionary, or Dictionary<string, string> firstItems corresponds to a dictionary uses the source dictionary keys as key, and first item in values in source dictionary as values.

This could be partially done by adding behavior in the getter/setter of keys and firstItems. When we call keys, we get keys from dictionary; or when we call keys = whateverTheListIs, dictionary may perform certain behavior as designed too.

But I would also like to have a "more functional" "accessor", for example, when we call firstItems.Add(aString, anotherString), we add an entry to the dictionary too; or when we call keys.Remove(yetAnotherString), we remove the entry in the dictionary.

Is their any way I can do that?

Edit:

Here is the scenario (of course you may change it, it's just for explanation):

public class Projection
{
  private Dictionary<string, List<string>> dictionary; //"backing field"

  public List<string> keys;
  public Dictionary<string, string> firstItems;
}

public static void DoSomething()
{
  Projection projection = new Projection();
  //Supposed to modify projection.dictionary too
  projection.keys = new List<string>();
  projection.keys.Add("A new Key");
}

Upvotes: 1

Views: 106

Answers (1)

aloisdg
aloisdg

Reputation: 23521

You can create your own Dictionary with inheritance :

class CustomDictionary<TKey,TValue> : IDictionary<TKey, TValue>
{
    // Implement the interface IDictionary here

    public void Add(KeyValuePair<TKey, TValue> item)
    {
        // create your logic
    }
}

You can use composition :

class CustomDictionary<TKey,TValue>
{
    private Dictionary<TKey,TValue> _dictionary;

    public void Add(KeyValuePair<TKey, TValue> item)
    {
        // create your logic
        _dictionary.Add();
    }
}

And my favorite way, you can use both :

class CustomDictionary<TKey,TValue> : IDictionary<TKey,TValue>
{
    private Dictionary<TKey,TValue> _dictionary;

    // Implement the interface IDictionary here
    // send the logic to your private Dictionary

    public void Add(KeyValuePair<TKey, TValue> item)
    {
         // create your logic
        _dictionary.Add(item.Key, item.Value);
    }
}

If you want to inherit directly from a Dictionary, you will face a problem. You cannot override the method Add() because its not a virtual method. A solution would be to hide it with the keyword new.

class CustomDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
    public new void Add(TKey key, TValue value)
    {
        // create your logic
        base.Add(key, value);
    }

    public void Add(KeyValuePair<TKey, TValue> item)
    {
        this.Add(item.Key, item.Value);
    }
}

Upvotes: 1

Related Questions