Inherited constructors


*** inherited constructors


 


This is a pet complaint of mine – I’ve never understood why you can’t inherit constructors.  People put forth all sorts of arguments against it, but to my mind, they can all be removed by one simple rule: any derived class inherits all constructors from it’s parent, if and only if it doesn’t construct any of it’s own!


That way, it makes it nice and easy to just “add a function” to a class…


 


The case where you want to add a function to a class is a fairly rare one. The more common one is where you do something beyond that. In those cases, if we allowed constructor inheritance, then there’s a reasonable chance that somebody will forget to do some initialization in a base-class constructor, and then bad things will happen. This is especially bad in the versioning case – if a new version of the base class shows up with a new constructor, you would automatically get a new constructor in your class. Bad.

Comments (23)

  1. Tom says:

    Not only that, but often times it isn’t apparent what is happening inside of a base constructor (aside from viewing the IL).

    If you want to override the constructor and add methods you would probably want to just use a different class, or use implementation.

  2. Thomas Eyde says:

    I see your point and vagely agree that inherited constructor is not good. Vagely, because I have yet to encounter a situation where I do not want to inherit them.

    Question 1: If I inherit a constructor and do nothing about it, that is, I don’t add any code so there are no overrides, how can I forget any base initializations? I still use the very same implementation that was before.

    Question 2: If I choose to add code, hence do an override (or new if you insist on the non virtual by default nonsense), then it is my responsibility to call any base constructors, right?

    Question 3: If you still think it is so bad, can you at least automate the coding for us? Once we finish the constructor name, let us choose from a list, then let the tool complete the signature with the call to base.

  3. I understand your problem with inheriting constructors, but why not abstract or required constructors? I still haven’t heard a good reason for this. In fact in serialization (XML and SOAP/Binary) both require a constructor that is specified in the docs, with no way to get the compiler to make sure you do the right thing. If you guys needed it, don’t you think we might need it too?

  4. Jason G says:

    That’s one specific example where they needed it in the entire framework. I doubt there are too many instances of that.

    One of the hardest things to get over when designing classes, is that it’s BAD for you to want total control over everything the user’s of your classes will do with them.

    For instance, if want to do a Null object implementation of your class, do I still have to do all of your constructors?

    What if I want to do a Singleton instance, or create a Factory, or I know that half of the parameters you want in your constructors should always be a certain set of values or my derived class won’t work, or……

    Trying to shoe horn everyone into your vision of how your classes and their descendants will work is just bad.

    ===============================================

    Being *Explicit* is a very good thing and something that keeps developers out of a lot of trouble. Inheriting constructors is not explicit.

  5. Darren Oakey says:

    Jason: – I don’t understand – as far as I see it, your entire post argues for flexibility, don’t expect what people are going to do etc etc – I read it as SUPPORTING inheritance of constructors… and then you turn around saying they are a bad thing??

    Now – lets think a little – we ALREADY have inheriting of constructors – in that the default constructor is inherited and available IFF you don’t define any constructors in the child class.. All I’m saying is that the same logic should apply to all the other constructors..

    Lets look at a concrete example of where you would use it right now (and PLEASE don’t mention that now that we have generics, we wouldn’t actually do this – I know!!!)

    We want a typed arrayList… so we want to just create

    private class EmployeeList : ArrayList

    {

    public new Employee this[int index]

    {

    get {return base[index] as Employee;}

    set {base[index] = value;}

    }

    }

    but we can’t actually do that – can we – we have to override three stupid constructors, each one just is an empty function calling the base constructor with the same arguments

    However, by doing this, we haven’t BROKEN anything… because if we do have the situation where we do want to say, Add a variable (let’s say max size for instance)

    private class EmployeeList : ArrayList

    {

    public EmployeeList( Icollection collectionToCreateFrom, int maxSize ) : base( CollectionToCreateFrom)

    {

    _maxSize = maxSize;

    }



    }

    We have now supplanted ALL of the ArrayList constructors. IE – you couldn’t do new EmployeeList().

    So, by allowing constructors to be inherited (if and only if no child constructors are defined) we lose absolutely nothing, we have NO potential damaging affects, and we gain heaps.

    And, for these sort of classes, like Thomas said above, if we add a constructor to the base class, we definitely DO (and always will) want to have that constructor available for the child class. Currently, it means we’d have to go and find all those classes inheriting from it, and add the constructor line 🙁

    I honestly can’t see ANY downsides!

  6. Daniel O'Connell says:

    I think we would lose quite a bit…not only would adding this probably break alot of code(it would actually break source compatibility), you lose a great deal of simplicity in the language. Inheriting constructors, as proposed above, makes it *much* easier to cause major effects by one minor change. What if you decide you want to add a new constructor to one child…you are suddenly in a situation where you have to write a half dozen or more constructors. I think doing that would cause people to decide to *not* write new constructors and instead resort to properties or methods that have to be setcalled before using the object. If you do need special code in one constructor you need to write all the constructors again as well. In essecne this solves a problem for maybe 25% of code, which will actually turn out to be a problem for atleast half of that, and means absolutly nothing for the remaining 75%. I don’t think its really worth it.

    I would be in support of better syntax for implementing base constructors, as I think the current way is pretty lame(even dropping the empty{ }’s would be a good start).

  7. Eric Newton says:

    I believe a good middle ground is a little more intellisense during class creation to address what constructors the base class has, and help you write it out… another way VS.Net becomes INVALUABLE! …I still dont know how some people write C# in notepad 😉

  8. Jason G says:

    Darren:

    I wasn’t arguing specifically against inheritance, but mainly against forcing a contract on constructors onto derived classes.

    Inititialization isn’t part of your object contract IMHO, but another part of your object collaborations. If a derived class wants to eschew your planned collaborations (because it has its own most likely.) then forcing a constructor it doesn’t want onto it is dangerous. I know developers who would use that feature religously, mainly due to a variant of Not Invented Here syndrome known as I Know Better Than You.

    With that said, I’m really finding it hard to grasp the semantics of what you are talking about.

    Basically, you are suggesting that if you do not define any constructors, then the base classes constructors would then be inherited?

    There is one small problem with that. Even if *you* don’t define any constructors, the C# compiler does. Hmm, I guess that would just mean that it would have to be purely a compile time language feature.

    Really though, I do see what you are saying. I think I just have a different opinion that the semantics of not explicitly defining a constructor is important in its own right.

    I think the final text block above is pretty much my whole opinion on it. I like explicitness. Constructor inheritance is implicit, and not clear to me. To find out how to construct the object, I have to check my source file if I have a constructor snuck in somewhere, and then go to the base class if I didn’t see one. Partial classes makes this even harder.

    Honestly, I could see it going either way. I think I would prefer additional IDE support for copying base class constructors over cosntructor inheritance.

  9. Thomas Eyde says:

    Huh? Constructor inheritance is implicit, and not clear, hence it’s bad? How’s that different from method inheritance? And why do you have to go to the base source? Have you lost your intellisense?

    And initialization is definitively a part of the object contract: You can’t create the object if you don’t fulfill it.

    And why is forcing a new constructor dangerous? No one has to use it if they don’t want to.

    Why don’t we just say no to anything but the default constructor? They behave just like static methods, so let’s use those instead.

    The way things are now, a constructor is technically not inherited, but it is still enforced on us. Don’t you just hate it when the compiler says "No overload for method ‘MyBase’ takes ‘0’ arguments" and point to a constructor which accepts exactly 0 parameters? You have to read the message twice to understand you forgot to CALL the base constructor.

  10. Jason G says:

    I really have no idea why I never express myself clearly 🙁

    RE: Forcing your derived classes to have a specific constructor.

    Constructors are special, and break a lot of rules. They are basically saying "This is what I need to do my thing".

    In that vein, constructors are more a part of your object collaboration structure and not part of your object’s responsibilities. It’s saying "This is what I need." and not "This is what I do."

    Thats probably part of why they decided to not allow constructor specifiers in interfaces. It’d just be silly.

    With all that said, I’m completely ambivalent towards constructor inheritance now. I can see it go either way, with no strong opinion.

  11. Kael Rowan says:

    I agree with Thomas. Constructors should be no different than any other inherited methods (other than they should all be virtual). Most of the arguments I’ve read so far against inheriting constructors is that nobody would want a new constructor in a base class to be inherited by an existing sub class without you knowing about it since it would circumvent the sub class’s construction. I don’t think this is any different than methods though – you wouldn’t want a new method in a base class to be inherited by an existing sub class without you knowing about it since it could circumvent the functions on the sub class. In other words, changing public signatures on existing classes (even if just expanding them) is already dangerous for methods (and properties) so it shouldn’t be used as an argument against inheriting constructors as well.

    I can see a large benefit for allowing constructor inheritance and no drawbacks that don’t already exist for inheriting methods and properties. C# (or the CLR) shouldn’t sacrifice power and flexibility to attempt to protect developers from themselves by not paying attention. Leave that to VB.NET 🙂

  12. Daniel O'Connell says:

    Of course there are drawbacks…for one, the number of constructors on a type could grow enormously, every object would have an empty default constructor anyway, since System.Object does; for another, you will end up with constructors that have *no* bearing on the object. Its not that they interrupt the construction so much as they shouldn’t be there at all. To really allow constructor inheritance you would also have to allow a way to remove any constructor from any instance…which would violate the Liskov Substituality principal and make virtual constructors messy and dangerous.

    Imagine:

    public class MyClass

    {

    public MyClass(MyBaseObject x)

    {

    }

    }

    public class MyDerivedClass

    {

    public MyDerivedClass(MyDerivedObject y)

    {

    }

    }

    If you allow constructors to inherit, MyDerivedClass suddenly has a constructor that takes MyBaseObject…although the entire point at derivation was to extend the class so it could handle the new types, chances are good that MyDerivedClass uses features introduced in MyDerivedObject and hence, passing it MyBaseObject breaks its purpose.

    Do you really think thats a good idea?

  13. Darren Oakey says:

    Daniel – I think you are missing a very important point – Exactly like the default constructor, constructors would be inherited IF AND ONLY IF NO CONSTRUCTORS ARE DEFINED.

    ie:

    class A

    {

    public A() {}

    public A(int y) {}

    }

    A has two constructors

    class B : A

    {

    }

    B has two constructors (no parameters and int)

    class C : A

    {

    public C( string x);

    }

    C only has ONE constructor (string)

    ie – you CANNOT say new C(10);

    but you CAN say new B(10);

    It is purely for the use when you want to just add or replace methods to an existing class… but we DO NOT CHANGE NORMAL OPERATION as far as properly extending a class – as soon as you start adding fields, you need to initialize them, and as soon as we put a constructor to do so, we have automatically removed ALL base constructors.

    (NOW – remember – you already use this EVERY DAY – the default constructor behaves exactly like this. How many times do you inherit from a class (eg ListBox) and don’t make your own constructor – I do it every day! But that works because the base class has a default constructor. All I’m saying is that all constructors should behave equally)

    A concrete example – if I go and inherit from listbox, and change it to be exactly the same, but have say a gradient in the background, of course if someone goes and changes ListBox to add a constructor so it can be setup with a set of items, I very much DO and ALWAYS WILL want my derived class to be able to be constructed the same way!

    However, if I happen to have made a listbox for a specific purpose (say to show a list of employees) – in which case I’d have a constructor that took a list of employees, I wouldn’t want anybody to be able to construct the listbox in any other way!!

    So – I think the rule is pretty simple, pretty unambigous, and would behave as you wanted in 99.99% of cases: "If you don’t specify a constructor in your child class, you automatically get all the constructors from the parent class". "If you DO, then only the constructors specified at that level are valid" It actually makes the model simpler, because suddenly the default constructor behaves exactly the same as all the other constructors.

    I CHALLENGE ANYBODY to come up with a concrete example where they wouldn’t want classes to behave as specified above!

  14. Daniel O'Connell says:

    Don’t need a concrete example. First off, what you are proposing is *NOT* inheritance, its compiler supported constructor generation that implicitly calls the underlying constructor. Not only is there quite a difference. What you are implying as the cause for a base constructor in a given class is incorrect. If no constructors are defined, the C# compiler implicitly emits a default constructor and tries to call teh default constructor on the base class(and if it doesn’t exist, you will get a compile time error). That is significantly different than assuming the default exists because the base has a default.

    The primary problem with this rule is it solves a problem that, personally, I don’t think is anywhere near widespread enough to matter. I don’t know about you, but I don’t derive from classes in ways which construction doesn’t matter very often. Why should the semantics of the entire langauge change so that 5-10% of code could be easier? What good does this do if I want to *add* a constructor to the underlying set…none. What good does it do if I want to modify one constructor…none. What good does it do if I want to *remove* only one constructor from teh set…none. Its only valid in the very narrow situation where one doesn’t care about construction, in all other situations you are still using the old behaviour. I think this feature would have more limited applicability than unsafe code and stackalloc, personally, especially as generics come and creating custom collections mostly goes out the window. Now, if those of you that are upset would sit down and try to determine a syntax that would solve *all* of the problems…I’d probably listen, hell if it was good enough I’d do an implementation in mono. But this is a lowest common denominator approach and it just isn’t good enough.

  15. Darren Oakey says:

    This is interesting actually. Reading people’s opinions is saying a lot about how people use inheritance.

    Now, for me, inheritance is typically a BAD thing. In most business cases, I think the same thing can be done better with containment.

    When I use patterns, for instance State – I will always use an interface, because even though there is an argument that the ReadOnlyState IS-A State, there is no _actual code_ I want it sharing with WriteableState – and I think Interfaces are a far beter pardigm. Actually, I’d be quite happy living in a world with ONLY interface inheritance – I think implementation inheritance reaches out and bites you, more often than not.

    The few times I find inheritance REALLY USEFUL is when I want to just "put in" functionality that I think _should have been there in the first place_.

    For instance: I HATE ANY duplicated code, even on the micro level. I don’t want my developers writing:

    if (theString.Instr( theOtherString) > -1)

    that’s just crap – I want them writing

    if (theString.Contains( theOtherString))

    and the only easy way to Contains and all my other little common string things, is to inherit from string…

    Another example: The ListView. All nice and everything, but every time I’ve used a listview, I’ve wanted: a) the columns to automatically rescale to exactly fit the size of the listview, b) the columns to sort when you click on the column header, and c) the ability to put icons in any column… So we always use my ResizingListView, which just inherits from ListView..

    In our system, there are basically several libaries which use inheritance a lot, and they form OUR new "system" framework – add features we thought should be there, do things like enforce company standards of look and feel, identity and so forth, do our type of OO->Relational modelling etc.

    That’s probably 85% of the use of inheritance in our system overall. And in not one of those classes would you find a constructor, because all we are doing is ADDING TO or CHANGING underlying functionality. The way we GET AT the objects will always be the same.

    If we do use inheritance up the line, especially if we implement anything coming out of something like design patterns, it is almost always interface inheritance.

  16. Daniel O'Connell says:

    Hrmm, that is an interesting stance. While I do alot with interfaces, I don’t rely on them totally because they do have some problems(namely performance(rarely) and the issues with interface versioning, its just not possible to grow an interface without breaking code).

    It also shows a difference in what we are working on. My last several projects havn’t even included UI’s or business objects. For example, one of the things I did a few months ago is write filesystem readers for ISO9660 and Joliet cd images. This is a prime situation where sharing code makes alot of sense, the only difference in the two is the existance of another sector and a different format for the file list. I was able to override two or three methods in the Joliet reader and get a completely working implementation without having to deal with any of the complexities of modes, etc twice(though, in this case the constructors would have likely been identical if any public ones had existed, but because the system had to be able to load an image without knowing the format ahead of time, I had to use nasty factory tricks to determine what class to use). However, in most cases I agree with you, as far as interfaces go. I see no need for multiple inheritance, although I do think that base class inheritance is valuable in more cases than just extending controls. Much of what I write uses an abstract base that implements the entire front end(public interface, including any relevent interfaces) and leaves protected abstract members that provide the core behaviour of a class in a way that is simpler than writing the whole class. While interfaces and containment could do this, I think a solidified object model helps the design.

    However, I find your string example rather odd…System.String is sealed.

  17. Eric Mutta says:

    Darren:>I CHALLENGE ANYBODY to come up with a concrete example where they wouldn’t want classes to behave as specified above!

    Good show of confidence there my friend, but as is always with these things, there are drawbacks:

    *breaks code.

    Suppose you define a ChildClass that inherits from ParentClass but does not define any constructors of its own. So in your code you start creating instances of ChildClass using the constructors it inherited from ParentClass and life is a joy. Then later ChildClass evolves to a point where it needs special initialisation. If you add a constructor to it, you break *every* line of code (your code and – worse – any other client’s code) where instances of ChildClass were being created using the ‘new’ operator.

    *increased semantic complexity.

    Compilers will now have to do more semantic checks on ‘new’ expressions. The details can get pretty esoteric but in short, the compiler’s symbol tables may need to be adjusted to allow inherited constructors to take part in symbol lookup and validation. This comes with a space-time cost and given C#’s OOP nature and heavy reliace on ‘new’, compilation times will be adversely affected. Slower compilation means poorer background-compiler performance, which means poorer intellisense experience, which means…

    *increased cognitive complexity.

    I dunno about others but I find it quite daunting when classes provide like 6 different constructors. Now this is happening *without* constructor inheritance, the number would increase if constructors could be inherited, even if you had a shallow class hierarchy. Having more than 3/4 ways to do the same thing (initialise an object) is a good recipe for cognitive opaqueness.

    There are probably more issues, but the above ones reveal that the cost/benifit ratio of the proposed feature is too low to justify it, IMO.

  18. sebmol says:

    From a library vendor perspective, having inheritable constructors is rather useful because it allows me to create new classes without cluttering up the source files with unnecessary code (in this case child constructors that do nothing else than invoke base class constructors).

    Exception classes are a great example of that. In C#, the ApplicationException class has four constructors, three of which I would have to implement as pure deferals in a derived class.

    Maybe, instead of default inheriting constructors, we could have some kind of syntax to pull in the base classes constructors explicitly. What do you guys think?

  19. Chuck Conway says:

    The entry lead me to believe you couldn’t inherit constructures. Unitl I found this link: http://www.csharphelp.com/archives/archive65.html

  20. MBA says:

    Helpful For MBA Fans.