Skip to content

Inheriting constructors in C#, VB.NET

Several times, I’ve come across the need for inheriting constructors in .NET, and I am constantly annoyed that it does not work. I’m writing a business objects layer, and what I’m trying to do is create some constructors in the base class that can initialize the objects in many different ways, eg:


Public Sub New() ' Create new object using default storage
Public Sub New(ByVal storage as Storage) ' Create new object using specified storage
Public Sub New(ByVal conditions as String, ByVal parameters() as Object) ' Load an object by the specified query, using default storage
Public Sub New(ByVal storage as Storage, ByVal conditions as String, ByVal parameters() as Object) ' Load an object by the specified query
Public Sub New(ByVal id as Object) ' Load an object by the specified primary key, using default storage

And so on. I like to provide many different ways in the base classes, to 1) make writing the objects that inherit from this as easy as possible, and 2) make writing client code as easy and flexible as possible.

Unfortunately, since you cannot inherit constructors (except for the default New() constructor, if that is specified in the parent..), you cannot do this. You have to define stub constructors in each inherited object which call the parent constructor, which ends up being a whole bunch of copying and pasting, and even more work if you ever change/add a constructor.

Eric Gunnerson posted a blog entry about inheriting constructors, and there is a good discussion on it in the comments. I completely agree with Darren Oakey who suggests that constructors should be inherited if and only if no constructors are defined.

This fits in with the default behaviour of inheriting the empty constructor, and generally is compatible with existing code. The only time it would break existing code is if you have an object with no constructors that inherits from another with a non-default constructor, and you specifically want your inherited object to have the default constructor.


Public Class A
Public Sub New(ByVal value as Integer)
End Class

Public Class B
Inherits A
End Class

In the implementation right now, B only has the default (no parameters) constructor. If this change is made, B will have New(ByVal value as Integer), so existing code that assumes it has no parameters will fail. The fix for this is to explicitly define a constructor for B as:


Public Class B
Inherits A

Public Sub New()
End Sub
End Class

One of the arguments against inheriting constructors seem to be that implicit operations are bad and confusing – however, in my view, having the default constructor implicitly added in the above case is exactly the same thing. Additionally, as is pointed out in the comment thread in Eric’s post, this is also how methods behave. Why should constructors be different?

Another option is to add a class attribute that would allow constructors to be inherited, eg:


<InheritConstructors(true)> _
Class B
Inherits A
End Class

It would really make the language more powerful, and allow writing simpler and nicer code. In a simple example:


Dim cust as Customer = Customer.Load("id = {0}", 123)

becomes:


Dim cust as New Customer("id = {0}", 123)

Be Sociable, Share!

Subscribe