9

After looking at this MSDN article, I am now wondering what the benefit, if any, is of defining a collection as a class that inherits from ObservableCollection. Are there any significant differences between this:

class MyCollection : ObservableCollection<MyObject> { }

class Class1
{
    private MyCollection _newCollection = new MyCollection();

    public Class1()
    {
        _newCollection.Add(new MyObject());
    }
}

and this:

class Class1
{
    private ObservableCollection<MyObject> _newCollection = new ObservableCollection<MyObject>();

    public Class1()
    {
        _newCollection.Add(new MyObject());
    }
}

Is there something I'm overlooking here?

Jason D
  • 2,634
  • 6
  • 33
  • 67
  • 1
    I'm a bit confused about what you're asking. If you need extra functionality that can be added to ObservableCollection by extending it, write a class that extends it. If you don't, you can just use ObservableCollection. – TheEvilPenguin Jul 26 '13 at 00:00
  • So I'm guessing in the case of the article I looked at, the author probably did it that way for simplicity's sake? – Jason D Jul 26 '13 at 00:01
  • 1
    An alternative to inheriting from a generic class (so consumers don't need to provide generic type arguments all the time) is to use a type alias, like so: `using MyCollection = ObservableCollection;` (the downside being you need to specify this in all of your files). – Dai Jul 26 '13 at 00:04

3 Answers3

11

One major benefit is that you can define the Add function, which makes inline initialization easier. So for example this:

class MyCollection : ObservableCollection<MyObject> 
{  
    public void Add(string prop1, string prop2)
    {
        base.Add(new MyObject { Prop1 = prop1, Prop2 = prop2 });
    }
}

Lets you write this:

MyCollection collection = new MyCollection
{
    { "prop1", "prop2" },
    { "prop1", "prop2" },
};

A second (related) benefit: if you're working with XAML, having a subclassed collection lets you define collection instances (for design/test cases) as markup, as in:

<local:MyCollection xmlns:local="MyNamespace">
    <local:MyObject Prop1="prop1" Prop2="prop2" />
    <local:MyObject Prop1="prop1" Prop2="prop2" />
</local>

Lastly, (and this is merely a matter of taste, I suppose) it doesn't hurt in general, and can help. Sometimes you end up needing more methods/properties for a given collection type. It's nice to have a typed subclass ready, without needing to refactor.

McGarnagle
  • 101,349
  • 31
  • 229
  • 260
  • 1
    +1 for the XAML usage, i've used it that way with a dummy class that inherits from `ObservableCollection` just for using it within WPF. However, in XAML 2009, it's entirely possible to use generic classes natively, so this technique loses value when you use XAML outside WPF. – Alejandro Jul 26 '13 at 00:32
2

In the example that you give, there is no particular benefit. In general I think it is fair to say that you usually should avoid inheritance if you are not extending or overriding the inherited class in some way. That being said your sample is not quite faithful to the sample from the article.

public class NameList : ObservableCollection<PersonName>
{
     public NameList() : base()
        {
            Add(new PersonName("Willa", "Cather"));
            Add(new PersonName("Isak", "Dinesen"));
            Add(new PersonName("Victor", "Hugo"));
            Add(new PersonName("Jules", "Verne"));
        }
...

In the MSDN sample, they have added additional logic in the classes constructor. In a real world example this class might have had a constructor that took a repository interface of some sort, or read from a file, or any number of things that are not part of the functionality of ObservableCollection So the answer to your original question is another question "Do you need to extend ObservableCollection< T >?"

cmsjr
  • 56,771
  • 11
  • 70
  • 62
2

The example is far from a good usage for inheritance, that particular adds little to nothing to the class.

Normally, you can think of subclassing it in the same way you would consider for any other class, when it provides useful features but you want something more. You may want for example a particular action to take on inserts, some special handling, implement an additional interface, or some different notification, then you inherit, and override/add members as you need.

A practical example is done in the MVVM framework for WPF Caliburn.Micro, where they have BindableCollection<T>, inheriting from ObservableCollection<T>, which performs thread UI marshalling in addition to notifying about changes.

Alejandro
  • 7,290
  • 4
  • 34
  • 59