8

The .NET Framework contains since version 3.0 the ObservableCollection<T>, but why isn´t there a ObservableKeyedCollection<TKey, TValue>.

Okay i could implement my own collection by deriving from KeyedCollection<TKey,TValue> and implementing the INotifyCollectionChanged interface, but whouldn´t it be a good addition to the .NET Framework.

Jehof
  • 32,386
  • 9
  • 115
  • 149

3 Answers3

2

The reason that there is no ObservableKeyedCollection (or any other such type which is merely a combination of other generic types) is because ObservableCollection is generic, and that makes implementation of an "ObservableKeyedCollection" as easy as this:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

public class DictionaryWatcher : ObservableCollection<KeyValuePair<string, object>>, IDisposable
{
    private NotifyCollectionChangedEventHandler watcher;
    private bool watching = false;

    public DictionaryWatcher()
    {
        watcher = new NotifyCollectionChangedEventHandler( ReportChange );
        CollectionChanged += watcher;
        Watched = true;
    }

    public bool Watched
    {
        get
        {
            return watching;
        }

        set
        {
            if (watching)
            {
                lock (this)
                {
                    CollectionChanged -= watcher;
                    watching = false;
                }
            }
        }
    }

public void Dispose()
{
    Dispose( true );
    GC.SuppressFinalize( this );
}

    public void Initialize()
    {
        this.Add( new KeyValuePair<string, object>( "First", 1 ) );
        this.Add( new KeyValuePair<string, object>( "Second", 2 ) );
        this.Add( new KeyValuePair<string, object>( "Turd", 3 ) );
        KeyValuePair<string, object> badValue = this[2];
        this.Remove( badValue );
    }

protected virtual void Dispose( bool disposing )
{
    if (disposing && Watched)
    {
        Watched = false;
    }
}

    private void ReportChange( object sender, NotifyCollectionChangedEventArgs e )
    {
        Console.WriteLine( "Change made: {0}", e.Action );
    }
}

While that is certainly not a one-liner program, most of it is boilerplate. Most importantly, it doesn't re-implement the ObservableCollection as you were suggesting; instead it fully utilizes it.

The reason that it "whouldn't be a good addition to the .NET Framework" is because when there's already one way to do something, creating another way to do it is a bad idea. The fewer ways there are to get some particular task done, the fewer ways there are to do it poorly. 8 )

The tools are provided, it's now all about how you use them.

Hope that helps!

Task
  • 3,540
  • 1
  • 19
  • 30
  • 10
    There are a lot of things available in the KeyedCollection which aren't in your solution. For example an indexer based on the key, prevent adding items with the same key, etc. So the above code might be boilerplate, but it is certainly not complete. The Framework is for giving us tools that are not only handy to use, but also complete in their implementation... – Jeroen Landheer Nov 26 '10 at 19:37
  • 3
    I agree with Jeroen. This answer doesn't have the fundamental capabilities of the KeyedCollection. I want to also point out that if ObservableKeyedCollection were provided by the framework, then we would have the fewest possible ways to do this--1--rather than everyone creating their own solution, many of which will be broken like this one. – totorocat Jan 14 '11 at 03:39
2

Please take a look at the ObservableKeyedCollection class implementation. It's pretty easy.

Sergey Brunov
  • 11,755
  • 7
  • 39
  • 71
1

I'd recommend you take a look at C5. It is a wonderful generic collection library that offers observable collections as standard for all of its collections, including Added, Inserted, Removed, RemovedAt, Cleared, and Changed. Additionally, the C5 collections all espouse the "programming to interface" ideal. All of the interfaces provides expose the full functionality of the underlying implementations—which is lacking in the System.Collections.Generic namespace. Additionally, there is thorough documentation. I highly encourage you to check it out.

Marcus Griep
  • 7,288
  • 1
  • 20
  • 23