Inheriting from ReadOnlyObservableCollection<T> and a Lesson about Constructors

I had need of returning a bindable collection from one of my classes, but didn’t want to allow the caller to modify the collection.  This generally requires a straightforward pattern in .NET: make a SomethingCollection class that derives from Collection<T> and a ReadOnlySomethingCollection class that derives from ReadOnlyCollection<T>, then only return the read-only version.  Most examples don’t bother with declaring the derived types, but I feel like it makes everything look better and the framework classes seem to favor declaring their own collection types as well.

I was having one heck of a time getting everything to work. I tried the most basic implementation:

public class ReadOnlySomethingCollection : ReadOnlyObservableCollection
{
}

This failed miserably with a fairly archaic error message:

‘full typename’ does not contain a constructor that takes ’0′ arguments

I struggled with this for a while. The error message was clearly correct; if you walk the inheritance tree there’s no base class that defines a parameterless constructor. Still, defining a constructor that matched the signature of the 1-parameter constructor didn’t seem to be solving the problem. I decided it’d be best to step outside my project and make a simple example project in preparation for asking forums and newsgroups what was going on. It turns out switching languages to VB .NET was a good idea, too, because its error message was much more helpful once I had the constructor in place:

First statement of this ‘Sub New’ must be a call to ‘MyBase.New’ or ‘MyClass.New’ becasue base class ‘…’ does not have an accessible ‘Sub New’ that can be called with no arguments.

I saw this, thought about it for a minute, then had a forehead-slap moment. When a class derives from another, it’s almost as if you have two objects glued together. The base class has to be initialized before the derived class can be initialized, because the derived class’s constructor must be able to assume its base members are in a good state. So, in my case, the compiler was trying to initialize a ReadOnlyObservableCollection<T>, but since there was no parameterless constructor it couldn’t. The solution was to do exactly what VB said: make sure I call some base-class constructor as my first action. I finally got it to work in C#:

public class ReadOnlySomethingCollection : ReadOnlyObservableCollection
{
    public ReadOnlySomethingCollection(ObservableCollection list) : base(list)
    {
    }
}

This isn’t the first time that it’s taken VB error messages for me to understand the solution to my problem; I wish there was more consistency between the error messages.

This entry was posted in .NET. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>