I have a question regards chaining constructors I read some question on StackOverflow and some c# articles but I cannot understand the topic fully. So I have a BaseClass that is inherited by DerivedClass. In the DerivedClass, I have no argument constructor but it's calling the base constructor using: base() and it also passing a value. Is this the primary purpose of the base keyword used in the constructor to pass a value to the inherited class from the derived one or is something more out there. And also in the derived class, we have a second constructor that takes 1 parameter and its using: this(). I can't understand why when I remove: this() from this constructor "VS" tells me "There is no argument given that corresponds to the required formal parameter "i" of BaseClass.BaseClass(int) ? Why I can't just have one argument constructor in the DerivedClass without using this()?
public class BaseClass
{
protected int _Num;
public BaseClass(int i)
{
_Num = i;
}
public int Num { get => this._Num ; set => _Num = value; }
}
public class DerivedClassA : BaseClass
{
private string _Name;
private int _AnotherValue;
public string Name { get => this._Name ; set => this._Name = value; }
public int AnotherValue { get => this._AnotherValue; set => this._AnotherValue = value; }
public DerivedClassA() : base(123)
{
_Name = "testing";
}
public DerivedClassA(int param2) : this() <-- Why i can't compile the program without the this() keyword here ?
{
AnotherValue = param2;
}
}
public class Program
{
public static void Main(string[] args)
{
DerivedClassA objA = new DerivedClassA(5);
}
}
I can't find a duplicate that exactly matches, so I'll provide an answer.
Imagine these classes:
public class Base
{
public Base()
{
}
}
public class Derived : Base
{
public Derived()
{
}
}
Try it online
When you initialize a derived class, you have to first initialize the base. In our example above, the Base class has a parameterless constructor, so the derived class can implicitly call it. If we add a base second constructor, this logic remains true, and the parameterless constructor will still be implicitly called:
public class Base
{
public Base()
{
}
public Base(int a)
{
}
}
public class Derived : Base
{
public Derived()
{
}
}
Try it online
But if we take away the parameterless constructor, Derived must now call the base constructor explicitly:
public class Base
{
public Base(int a)
{
}
}
public class Derived : Base
{
public Derived() : base(1)
{
}
}
Try it online
So what happens if we add an extra derived class constructor? Well, that also has to call the base class (either directly, or indirectly):
public class Base
{
public Base(int a)
{
// this method body is executed first
}
}
public class DerivedA : Base
{
public DerivedA(string name, int val) : base(val)
{
// this method body is executed second (last if you used this constructor, e.g. new DerivedA("hello", 1) )
}
public DerivedA() : this("test", 5) // this will call the constructor above, which will first call base. So the final chain is: base, constructor above, this constructor
{
// this method body is executed third (last if you used this constructor, e.g. new DerivedA() )
}
}
public class DerivedB : Base
{
public DerivedB(string name, int val) : base(val)
{
}
public DerivedB() : base(5) // this will call the base constructor, and then this constructor. The constructor above will not be used.
{
}
}
Try it online
Note that all classes have a parameterless constructor when no other constructor is defined, so the following two examples are equivalent:
public class BaseA
{
}
public class BaseB
{
public BaseB()
{
}
}
You'll note that SharpLab shows the compiler removed the empty constructor from BaseB() since it's superfluous.
Finally, a derived class without an explicitly defined constructor, will still call the base class constructor implicitly:
public class Base
{
public Base()
{
// this method body is executed first
Console.WriteLine("Base constructor");
}
}
public class Derived : Base
{
}
Try it online
So to summarise: unless your base class has a parameterless constructor, your derived class constructors have to either call a base constructor directly, or indirectly through another derived class constructor. Obviously you only need to call a single base constructor method, as with any other class instantiation. You don't need matching derived methods for each base method, so long as you can construct the base with the values you do have.
Related
I have a desing question. Lets say I have a base class, and many derived classes.
class MyBase
{
MyBase()
{
Record();
}
void Record()
{
/// this line is able to handle every object
Recorder.Process(this);
}
}
class DerivedA : MyBase
{
public int SpecialPropertyOfA { get; set; }
DerivedA(int specialPropertyOfA)
{
SpecialPropertyOfA = specialPropertyOfA;
}
}
class DerivedB : MyBase
{
public string SpecialPropertyOfB { get; set; }
DerivedA(string specialPropertyOfB)
{
SpecialPropertyOfB = specialPropertyOfB;
}
}
As you may deduce, I want to record derived classes with all their properties set. But the above example cannot record the special properties of derived classes since they are not set when the Record method called.
One way to overcome this is to make Record method protected and call it as the last line of derived classes constructors. But this violates my base principals(every derived class should be recorded right after initialization). I want to make this mandotory by design.
Any ways to handle this?
Take a look again at what you're trying to do.
Remember that base class constructor is called before the derived class's constructor.
MyBase()
{
Record();
}
void Record()
{
Recorder.Process(this); // <-- What is "this" ?
}
What would be the value of this at this point?
The instance has not been constructed yet, the derived class's constructor hasn't event been called so there's no reference to this, hence, you can't use it here.
You'll have to call this method after the instance has been fully constructed.
A way to overcome this is using a factory method:
public static class MyBaseFactory
{
public static MyBase CreateDerivedA()
{
int specialPropertyOfA = // ...
MyBase instance = new DerivedA(specialPropertyOfA);
Recorder.Process(instance);
return instance;
}
public static MyBase CreateDerivedB()
{
string specialPropertyOfB = // ...
MyBase instance = new DerivedB(specialPropertyOfA);
Recorder.Process(instance);
return instance;
}
}
My aim is to write an abstract base class which contains a method for deriving “child instances”. In this method already some computation is done which is common in all deriving classes.
The difficulty is that the base class is not able to create the child class on its own. So I introduced a type parameter T in my base class and a protected abstract method which shall return an instance of T.
public abstract class Base<T> where T : Base<T>
{
public T GetChild()
{
string param = ComplexComputation();
return NewInstanceFrom(param);
}
protected abstract T NewInstanceFrom(string param);
}
// --- somewhere else: ---
public class Derivative : Base<Derivative>
{
public Derivative() { }
protected sealed override Derivative NewInstanceFrom(string param)
{
return new Derivative(param);
}
private Derivative(string param)
{
// some configuration
}
}
The disadvantage of this approach is that I cannot ensure that NewInstanceFrom is only invoked by the base class. It could also be invoked by classes inheriting from Derivative. That’s what I want to avoid.
So I could encapsulate the functionality in a private class or delegate:
public abstract class Base<T> where T : Base<T>
{
public T GetChild()
{
string param = ComplexComputation();
return subElementDerivator(param);
}
protected Base<T>(Func<string, T> subElementDerivator)
{
this.subElementDerivator = subElementDerivator;
}
private Func<string, T> subElementDerivator;
}
// --- somewhere else: ---
public class Derivative : Base<Derivative>
{
public Derivative()
: base(deriveSubElement)
{
}
private Derivative(string param)
: base(deriveSubElement)
{
// some configuration
}
private static Derivative deriveSubElement(string param)
{
return new Derivative(param);
}
}
But this introduces a new object.
Is there a simpler way to prevent access to a functionality (which the base class shall have access to) from heirs of Derivative?
You can use explicit interface implementation to hide your factory method. Any client can still call the Create method after casting but at least intellisense won't help developers.
public interface ISecretFactory<T>
{
T Create(string param);
}
public abstract class Base<T> where T : Base<T>, ISecretFactory<T>
{
public T GetChild()
{
// We are sure type T always implements ISecretFactory<T>
var factory = this as ISecretFactory<T>;
return factory.Create("base param");
}
}
public class Derivative : Base<Derivative>, ISecretFactory<Derivative>
{
public Derivative()
{
}
private Derivative(string param)
{
}
Derivative ISecretFactory<Derivative>.Create(string param)
{
return new Derivative(param);
}
}
public class SecondDerivative : Derivative
{
public void F()
{
// intellisense won't show Create method here.
// But 'this as ISecretFactory<Derivative>' trick still works.
}
}
The additional object can be avoided by moving the ComplexComputation to the constructor of the base class and making the GetChild method abstract to let the deriving class pick a correct constructor there.
But how to return the computed value param in base constructor to the invoking derivate constructor? A possibility is to use the out parameter modifier. But because in C# 5.0 we are unfortunately not able to declare the variables before (or within) the base constructor call, we need to take the parameter along in the derivative constructor.
public abstract class Base<T> where T : Base<T>
{
public abstract T GetChild();
protected Base(T parent, out string param)
{
param = ComplexComputation();
}
protected Base()
{
}
}
// --- somewhere else: ---
public class Derivative : Base<Derivative>
{
public sealed override Derivative GetChild()
{
string param;
return new Derivative(this, out param);
}
public Derivative() { }
private Derivative(Derivative parent, out string param)
: base(parent, out param)
{
// some configuration
}
}
In my case I could leave the param from the constructors away, instead I stored it in a public property.
This approach except the pesky necessary hack looks relatively clean to me, but it does not “scale” when multiple overloadings of GetChild are necessary.
Maybe in C# 6.0 it is possible to declare the param directly in the base constructor invocation. https://msdn.microsoft.com/de-de/magazine/dn683793.aspx
I have some doubts in my below codes,
public class ClassA: BaseClass
{
public ClassA(UIElement element)
: base(element)
{
}
}
public class ClassA: BaseClass
{
public ClassA(UIElement element)
{
}
}
What is the difference between the above codes?
Doubts:
1.It is necessary to call base constructor
2.What is the use to Call the base constructor
3.If we didn't call base constructor it calls implicitly.
Any one please provide suggestion for this.
the first one instructs to use the BaseClass(UIElement) constructor, while the other one will use BaseClass() to be initialised instead.
To your questions; it all depends on if it makes sense to initiase BaseClass with the passed element or not.
Not always, if you don't specify anything then base() will be called
base() as you already did
Yes
In each case a base constructor is called, just implicitly and using the default in the latter case - in the first case it's using an explicit base constructor which accepts an argument. If no default parameterless constructor existed on the base class then an error would be encountered if it wasn't explicitly called by the user in order to provide the required input.
So, it's only necessary to call if you need to pass input to a specific constructor or a default public constructor is not defined.
1-3. no it's not necessary it call it automagically if the base calss contain a constructor without parameter
2. you use base when you inherit from another class, the part you inherited need to be constructed too so you have to call the base constructor
Please note 2 more things using chained contructors
The Base Contructor is always called before the actual constructor.
The constructors can have different accessabilities like private or public. You cannot chain every constructor from the base to the derived class.
The first one passes a parameter to the base constructor, while the second one uses the default (parameterless constructor).
public class Human
{
public string Name { get; set; }
public Human()
{
Name = "No name";
}
public Human(string name)
{
Name = name + " Jr.";
}
}
public class Male : Human
{
public Male() {}
public Male(string name) : base(name) {}
}
public class Female : Human
{
public Female() { Name = "Girl"; }
}
var unnamedHuman = new Human();
//unnamedHuman.Name == "No name"
var namedHuman = new Human("Jon");
//namedHuman.Name == "Jon"
var unnamedMale = new Male();
// unnamedMale.Name == "No name"
var namedMale = new Male("Chris");
// namedMale.Name == "Chris Jr";
var unnamedFemale = new Female()
// unnamedFemale.Name == "Girl"
The logic:
When you initialize a child class (by calling their ctor), first its base class constructors are called in order (top-down), the final one would be your child class' constructor you invoked.
By default, the default parameterless contructor is used but you can specify and pass arguments to the base constructor by using base(parameter1, p2).
If your BaseClass looked like:
public class BaseClass
{
private readonly _element;
public BaseClass(UIElement element)
{
_element = element;
}
}
Then you would absolutely have to call the base constructor, because it's the only constructor that BaseClass has.
If it looked like this:
public class BaseClass
{
private readonly _element;
public BaseClass()
{
_element = default(UIElement);
}
public BaseClass(UIElement element)
{
_element = element;
}
}
Then you would absolutely have to call the base constructor if you wanted to set the element, as it can only be set in the constuctor.
If it looked like this:
public class BaseClass
{
private _element;
public BaseClass()
{
_element = default(UIElement);
}
public BaseClass(UIElement element)
{
_element = element;
}
public UIElement Element
{
get{ return _element; }
set{ _element = value; }
}
}
Then you could choose between:
public class ClassA: BaseClass
{
public ClassA(UIElement element)
: base(element)
{
}
}
public class ClassA: BaseClass
{
public ClassA(UIElement element)
{
Element = element;
}
}
However, the former is clearer and doesn't have a period where Element returns the default (null) during the overall construction.
In all, consider that ClassA is a type of BaseClass. In creating a sensible instance of ClassA you have to do everything entailed in setting up a sensible instance of BaseClass. It is the job of the constructor to make sure this happens. Lean toward calling the base constructor as much as is meaningful.
If I have this code in C#:
public abstract class Parent
{
private int x;
public Parent(int x)
{
this.x = x;
}
public abstract void foo;
}
public class Child
{
public override void foo()
{
x = x + 10;
}
}
I get error that:
Parent does not contain constructor that takes 0 arguments.
How can I fix it, without creating non-parametric constructor?
You can create a constructor in Child, e.g.
public Child(int x) : base(x)
{
}
Constructors are not inherited - but if you don't supply any constructors at all, the C# compiler tries to create one equivalent to this:
public Child() : base()
{
}
That's what's failing here, because there isn't a parameterless base constructor to call.
Your derived class constructor doesn't have to have the same parameters as the base class constructor of course - so long as it passes appropriate arguments to a base constructor, that's fine. For example, you could write:
public Child() : base(0) // Default to x = 0
{
}
See my article on constructors for more details.
By manually invoking Parent's constructor:
public class Child: Parent {
public Child( )
: base(0) { }
public override void foo( ) {
x = x + 10;
}
}
That is because there is an Implicit call to a constructor with zero argument.
So you need to add an explicit call:
public Child(int x) : base(x)
{
}
Or instead, you can add zero argument contructor in parent itself:
public parent() { }
In the class below what does the "owner" argument do to both myClass and the base class?
public class Base
{
public myClass(owner) : base (owner) { }
}
If you have two classes, one is a base class the other a derived class, when you create constructor for the derived class, you can pass arguments to the base clas.
public class Base
{
private string Test = "";
public Base(string test)
{
Test = test;
}
}
public class Derived : Base
{
public Derived(string test) : base(test) // - This will call public Base(string test)
{
}
}
The following would compile and seem to fit your scenario minus the fact that you're not using the verbatim identifier #:
public class Base
{
public Base(myMethod owner)
{
}
}
public class #new : Base
{
public #new(myMethod owner) : base(owner)
{
}
}
The previous example demonstrates how to pass a constructor argument down to the base class' implementation.