DuplicateDictionary - A dictionary-like class which allows duplicates Since I couldn't find any good answers I made my own class called DuplicateDictionary for personal usage. I would like some tips to improve it.

public class DuplicateDictionary&lt;TKey, TValue&gt;: List&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;
{
    public DuplicateDictionary()
    {

    }

    public DuplicateDictionary(List&lt;KeyValuePair&lt;TKey, TValue&gt;&gt; list)
    {
        foreach(KeyValuePair&lt;TKey, TValue&gt; kvp in list)
        {
            this.Add(kvp);
        }
    }

    public DuplicateDictionary(Dictionary&lt;TKey, TValue&gt; dictionary)
    {
        foreach(KeyValuePair&lt;TKey, TValue&gt; kvp in dictionary)
        {
            this.Add(kvp);
        }
    }

    public TValue this[TKey index]
    {
        get
        {
            this.ContainsKey(index);
            return this[index];
        }
        set
        {
            this[index] = value;
        }
    }

    public void Add(TKey key, TValue value)
    {
        this.Add(new KeyValuePair&lt;TKey, TValue&gt;(key, value));
    }

    public bool ContainsKey(TKey key)
    {
        foreach(KeyValuePair&lt;TKey, TValue&gt; kvp in this)
            if(kvp.Key.Equals(key)) return true;

        return false;
    }
}


This class is useful for log things. I use it to log a calculator's past functions and numbers, and once equals is pressed, adds all the past numbers with the functions.
Such a data structure already exists, and is called ILookup&lt;TKey, TElement&gt;. It can be created using the ToLookup extension.


  The ToLookup&lt;TSource, TKey&gt;(IEnumerable&lt;TSource&gt;, Func&lt;TSource, TKey&gt;) method returns a Lookup&lt;TKey, TElement&gt;, a one-to-many dictionary that maps keys to collections of values. A Lookup&lt;TKey, TElement&gt; differs from a Dictionary&lt;TKey, TValue&gt;, which performs a one-to-one mapping of keys to single values.


var list = new List&lt;Tuple&lt;string, int&gt;&gt;
{
    Tuple.Create("a", 1),
    Tuple.Create("a", 2),
    Tuple.Create("a", 3),
    Tuple.Create("b", 4),
    Tuple.Create("c", 5)
};

var lookup = list.ToLookup(t =&gt; t.Item1, t =&gt; t.Item2);

foreach(var kv in lookup)
{
    Console.Write(kv.Key);
    Console.WriteLine(" - " + string.Join(", ", kv));
}

// prints
// a - 1, 2, 3
// b - 4
// c - 5


As Vince pointed out, your DuplicateDictionary will suffer from slow access. Lookup won't.