1

I'm sure this question is somewhere else but can't find it.

I have an abstract class that will be the base for other classes. want for the base class to have its base constructor inaccessible, and for the child classes not being able to edit the behavior, forcing them to use another constructor.

public abstract class BaseClass
{
    protected int X;
    private BaseClass() { } // Problematic accessor
    public BaseClass(int x)
    {
        X = x;
    }
}

public class Child : BaseClass
{
    public Child(int x)
    {
        X = x + 5;
    }
}

If I set the BaseClass() base constructor private it doesn't compile, but if I set it to protected, Child can override it.

There is a way to block Child modifying the base constructor?

EDIT: I want the base constructor to be inaccessible outside the class too.

Guillermo Mestre
  • 490
  • 3
  • 16
  • call constructor with parameter from child class `public Child(int x):base(x)` – ASh Sep 11 '15 at 10:25
  • 2
    Looks to me like the problem you're facing isn't blocking the private constructor from being used - it's *using* the public constructor. See http://stackoverflow.com/questions/12051 And no, subclasses can never "override" constructors. – Jon Skeet Sep 11 '15 at 10:26
  • 1
    Well, mission accomplished. "it doesn't compile" == successfully prevented derived class from using that constructor. There is no question here. It is never going to be called, you can simply remove it. – Hans Passant Sep 11 '15 at 10:45

3 Answers3

2

If you don't want do anything in the

  BaseClass()

constructor, just remove it (BaseClass has an explicit constructor and that's why doesn't have a default one):

  public abstract class BaseClass
  {
      //TODO: probably you want a property to read X
      private int X; // <- private looks better for fields
      public BaseClass(int x)
      {
          X = x;
      }
  }

As for Child class you have to invoke its base constructor, i.e. base(int x):

public class Child : BaseClass
{
    public Child(int x)
      : base(x + 5) // since X is private, let's move logic into the call
    {
    }
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • I just forgot that "it has an explicit constructor and that's why doesn't have a default one" – Guillermo Mestre Sep 11 '15 at 11:31
  • @Guillermo Mestre: if you *haven't* implement any constructors, C# states that in fact there's a default paramaterless one. But when you've *explictly implemented* at least one constructor, C# states that you've implemented *all the possible* constructors – Dmitry Bychenko Sep 11 '15 at 11:35
1

You need to use the correct base class constructor to do what you want:

public class Child : BaseClass
{
    public Child(int x) : base(x)
    {
        X = X + 5;
    }
}

Note that the Child constructor body now uses the protected field X, not the parameter x.

Johann Gerell
  • 24,991
  • 10
  • 72
  • 122
0

Just omit the parameter-less constructor altogether. Now, every derived class is forced to call public BaseClass(int x).

Sebastian Negraszus
  • 11,915
  • 7
  • 43
  • 70