Q:

How to modify ILookup object in C# 4.0?

Before .NET 3.5 was released, I use 
Dictionary<TKey, List<TValue>> 

for containing data. But I just found that .NET 3.5 provides new collection type that is ILookup class that can represent my old complex data type.
I always create ILookup object by using LINQ extension method (ToLookup method). But I do not know how to modify ILookup object.
Is it possible? Or I need to create by using union method and call ToLookup method again.
Thanks,

A:

You don't, it's immutable.  You have listed both of the reasonable options; either to use a dictionary of sub-collections or to keep creating new lookups.

A:

Here is an example of an implementation of ILookup that can be manipulated.  It wraps around a Dictionary of List's of elements.  It is completely generic.  I couldn't think of a better name. :)
public class LookupDictionary<TKey, TElement> : ILookup<TKey, TElement>
{
    private Dictionary<TKey, List<TElement>> _dicLookup = new Dictionary<TKey, List<TElement>>();

    public LookupDictionary()
    {

    }

    public LookupDictionary(ILookup<TKey, TElement> a_lookup)
    {
        foreach (var grouping in a_lookup)
        {
            foreach (var element in grouping)
                AddElement(grouping.Key, element);
        }
    }

    public IEnumerable<TElement> AllElements
    {
        get
        {
            return (from key in _dicLookup.Keys
                    select _dicLookup[key])
                    .SelectMany(list => list);
        }
    }

    public int Count
    {
        get 
        {
            return AllElements.Count();
        }
    }

    public IEnumerable<TElement> this[TKey a_key]
    {
        get 
        {
            List<TElement> list;
            if (_dicLookup.TryGetValue(a_key, out list))
                return list;

            return new TElement[0];
        }
    }

    public bool Contains(TKey a_key)
    {
        return _dicLookup.ContainsKey(a_key);
    }

    public void Add(TKey a_key, TElement a_element)
    {
        AddElement(a_key, a_element);
    }

    public void RemoveKey(TKey a_key)
    {
        _dicLookup.Remove(a_key);
    }

    public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator()
    {
        return GetGroupings().GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return (GetGroupings() as System.Collections.IEnumerable).GetEnumerator();
    }

    private void AddElement(TKey a_key, TElement a_element)
    {
        List<TElement> list;

        if (!_dicLookup.TryGetValue(a_key, out list))
        {
            list = new List<TElement>();
            _dicLookup.Add(a_key, list);
        }

        list.Add(a_element);
    }

    private IEnumerable<IGrouping<TKey, TElement>> GetGroupings()
    {
        return from key in _dicLookup.Keys
               select new LookupDictionaryGrouping<TKey, TElement>
               {
                   Key = key,
                   Elements = _dicLookup[key]
               } as IGrouping<TKey, TElement>;
    }
}

public class LookupDictionaryGrouping<TKey, TElement> : IGrouping<TKey, TElement>
{
    public TKey Key
    {
        get;
        set;
    }

    public IEnumerable<TElement> Elements
    {
        get;
        set;
    }

    public IEnumerator<TElement> GetEnumerator()
    {
        return Elements.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return (Elements as System.Collections.IEnumerable).GetEnumerator();
    }
}

