Search code examples
c#.netconstructorlanguage-designroslyn

Implicit chain constructor in .NET


Why is there no implicit chain constructor to the base class?

What I mean? Let's look at the following classes:

class Person
{
    public String Name { get; set; }
    public Person(string name)
    {
        Name = name;
    }
}

class EnhancedPerson : Person
{
    public int Age { get; set; }
}

If you try and compile this code it won't compile. As you can see Person depends on a name and makes it clear, you won't construct a Person without a Name.

Why is there no implicit EnhancedPerson constructor, who chains to the base constructor for each Person constructor?

Just to contestualize: I started asking myself this question creating controllers with injectable dependencies since some of those dependencies were present in all of my controllers (and I wanted to make it clear that they were needed), I created a base class and I found out that it is very annoying to re-create all the constructors...

P.s. I do know that there are also some others programming patters like having a public no-arguments constructor and public properties for dependencies, but ... that's another story.

I'm not looking for a way to reimplement this, I'm just trying to understand why it's not possible or why it was not done.


Solution

  • The "real" reason can only be answered by the people who defined the language, but I can speculate...

    There are various compile time errors that can be resolved automatically, for example:

    int mul(int c, int n) {
      int total = 0;
      for(i = 0; i < n; i++) {
        total += c;
      return total
    }
    

    Code above has 3 errors, with 3 obvious solutions:

    1. i is undefined
      A compiler could easily deduce i to be an int type and be local to the for statement.
    2. The for block is missing the closing curly bracket
      A compiler could "be smart about it" and know that the missing bracket is before the return ... statement merely because having a return as part of the for block without any branching makes no sense.
    3. return total is missing a semicolon
      Obviously simple to "auto-correct" at compile time.

    So why doesn't the compiler do that? why doesn't this happen in any language really?
    Well, the simple reason is that it's just dangerous without justification. Yes, these all seem like logical solutions to small mistakes or details overlooked, but in reality letting the compiler iron-out these types of problems can cause a lot of unexplained behavior (what if the developer really did want to return after the first iteration?). On the other hand, the cost of not solving these issues and alerting them instead is quite cheap. It lets the developer know exactly what's wrong and if the solution really is that simple it should take no more then a few moments to correct manually.

    The trade-off here is quite easy to choose, provide the developer with enough information so that the issues can be solved quickly and leave nothing to chance!

    The same holds true to the "implicit inherited constructor" suggested in the question... Yes, the compiler could do that, easily... but what if the developer really meant to do some real work in the constructor, but forgot? shouldn't the compiler assist by erroring out of the compilation?