10

I just read http://blog.gurock.com/articles/creating-custom-exceptions-in-dotnet/

I don't know when it is written. It says:

"Since C# unfortunately doesn’t inherit constructors of base classes, this new type only has the standard constructor with no parameters and is therefore relatively useless."

This says the same in 2010: C#: inheriting constructors

Is this still true?

EDIT: Following on from answers, I'm sure there would be a way around the default parameterless constructor. Are there other reasons for lack of constructor inheritance?

Community
  • 1
  • 1
cja
  • 9,512
  • 21
  • 75
  • 129
  • 1
    It's still true (and it's still true for C++ and Java too ;) See http://stackoverflow.com/questions/426484/why-are-constructors-not-inherited for some discussion. – Matthew Watson Feb 08 '13 at 09:52
  • Take a look at the spec: http://msdn.microsoft.com/en-us/library/ms228593.aspx – Jocke Feb 08 '13 at 09:54

5 Answers5

14

Constructors have never been inheritable in the entire lifetime of the C# language. That hasn't changed in C# 5.0: at the end of section 1.6.7.1 of the C# 5.0 spec, it still says:

Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

So it still holds true today, and I imagine it will remain so in the foreseeable future.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • 1
    Perhaps mention you can access the constructor in the base class explicitly, as that's a solution many will be looking for. – Xonatron Oct 16 '18 at 19:00
5

You have to explicitly call the constructor of the base class, unless the base class defines a default constructor. So yes they are not inherited.

Which sometimes lead to a bunch of boiler plate code where you do nothing than pass arguments from one constructor to another

public class NegativArgument : Exception {
     public NegativeArgument() : this("The number given was less than zero"){}
     public NegativeArgument(string message) : this(message,null){}
     public NegativeArgument(string message, Exception inner) : base:(message,inner){}
}

but what if you had an Exception type that should always have the same message? how would you solve that if the constructors were inherited? The exception class has a constructor that accepts a message so creating a new Exception type would in that case get that constructor too, not inheriting constructors makes it easy

public class NegativArgument : Exception {
     public NegativeArgument() : base("The number given was less than zero"){}
}

If the base class does not have a default constructor you will have a compile error if you do not explicitly call a base class constructor.

Rune FS
  • 21,497
  • 7
  • 62
  • 96
  • I think Delphi gets round the latter problem by having classes with lots of protected members; these classes are not supposed to be instantiated. Descendants can raise the visibility of members for use. – cja Feb 08 '13 at 10:18
  • 1
    @cja just as you can expose a construtor from a base class. The syntax is in the first example :) – Rune FS Feb 08 '13 at 10:54
  • 1
    I am creating a custom Exception and found myself redefining the constructors on derive classes. google brought me here. I guess I dont have a choice but to redefine. :) – Jaime Sangcap Sep 22 '14 at 09:05
1

You should call them explicitly the constructor of the base classes. They are not inheritable.

Didn't change anything about them.

Check out : Constructors (C# Programming Guide)

From the spec §1.6.7.1:

Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

http://msdn.microsoft.com/en-us/library/ms228593.aspx

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
1

Constructors are not inherited in C#.

If they were, then every class would have a default parameterless constructor (because all classes derive from Object and Object has a default parameterless constructor).

Many classes should only be constructed with specific values; this would be impossible to ensure if every class had a default parameterless constructor.

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
0

This answer is based upon the section "Constructors are not inherited" near the bottom of this entry on Jon Skeet's blog.

Summary

There are many cases in which a derived class may require information beyond that contained in the base class. Jon gives the example of the FileInfo class which requires additional information to be well-defined. Namely, that of the file for which info is to be provided

Any suggested 'fix' for this would entail overriding things in a way that prevents constructing such derived objects using the inherited constructors. However, knowingly requiring derived classes to override their base classes in a way that makes them more restrictive goes against best practice. (see: this question for Jon's discussion of the Liskov Substitution principle and the importance of being able to use derived classes wherever their base can be used.)

Additionally, from just a maintenance perspective, forcing manual override of constructors would make it difficult to reason about future behavior should the base class constructors change, and would entail having to always check, and often modify, any derived classes when new constructors are added to the base. Even a few of these would be problematic; but in cases where there are dozens or more such classes (and derived classes of those classes, etc.), maintenance and QA will quickly become a nightmare.

shelleybutterfly
  • 3,216
  • 15
  • 32