I have tried to understand but still not sure. If there is a constructor in the base class, the derived classes will always call it? I know they can override it (not correct term here, I know - I mean add code to their constructors) but I assume if the constructor is defined in the base class, the derived ones will always call it. Is that true?
Yes, if there is a parameterless constructor it will always be called. If there is more than one constructor, you can choose which one to call with the base keyword:
class Parent {
public Parent() {}
public Parent(int x) {}
}
class Child : Parent {
public Child(int x) : base(x) {
}
}
If there is no parameterless constructor, you will be forced to do this:
class Parent {
public Parent(int x) {}
}
class Child : Parent {
// This will not compile without "base(x)"
public Child(int x) : base(x) {
}
}
If there is only a parameterless constructor in the base class, the child class constructor will always call it first. On the other hand if you have other constructors defined in the base class, then the child class will have an option which base constructor to call.
Related
I have an abstract base class from which I derive two classes. The abstract class has a protected field which is initialized by constructors in the derived classes. Each of the derived classes has two constructors, the first constructor of each class initializes the field and the second constructor modifies the initialization of the first by calling the first constructor. The second constructor of both derived classes are exactly the same but the first constructor is different between the two derived classes. Is there some way to put the second constructor in the base class?
Here is an example to illustrate what I'm trying to say:
public abstract class A {
protected int[] field1;
public void someMethod() {
//somethingsomething
}
}
public class B : A {
public B() {
//body X
//this initializes field1 in some way
}
public B(bool p) : this() {
//body Y
//this initializes field1 in some way + modification
}
}
public class C : A {
public C() {
//body Z
//this initializes field1 in another way
}
public C(bool p) : this() {
//body Y
//this initializes field1 in another way + modification
}
}
What I would like to do, is to find some way so as to not have to repeat body Y twice. I was thinking of putting body Y of B(bool p) and C(bool p) in a constructor in class A as A(bool p), then have B(bool p) and C(bool p) call the base class constructor with : base(bool p) followed by an empty body, but then realized the base class constructor would have to call the derived class constructor.
This sounds stupid to me too. Although I am not sure, it's because I have this feeling that calling something from a derived class from a base class is something that can only be done at run time and there really is no way to check this at compile time. I'm just trying to find a way to follow the DRY principle.
Thanks.
Short answer: no. That would be breaking the object-oriented paradigm, so you wouldn't want to be able to do that anyway. Think about it this way: an abstract base class can be extended by an arbitrary number of classes, but if it was tightly coupled to one of the child classes, how would that impact the other ones?
public class BaseClass {
// Call child class constructor
public BaseClass() : A() { }
}
public class A : BaseClass {
public A() { ... }
}
// How should BaseClass handle this? There is no constructor named "A."
public class B : BaseClass {
public B() { ... }
}
If you want the base class and derived class to share some functionality, you should make it a protected method in the base class. That way, you can call that method from the constructor.
You could also make a constructor on the base class that provides the common functionality and call it from the child class with : base(...).
The only way a base class can trigger a derived behavior is through polymorphism (having a virtual method in B, and overriding it).
But there's some other way that might be much more inuitive in your case. For example:
public class C : A {
public C() {
//body Z
//this initializes field1 in another way
}
public C(bool p) : base(p) {
//this initializes field1 in another way + modification
}
}
Please note that in your example, B's default constructor calls A's default constructor, as well as C's default one calls B's default one.
Lastly, you can also consider having a second constructor in A that receives field1 initial value as a parameter, but it depends if your instructions are order-dependent.
If you precise what your constructors do exactly, I might have a more decisive answer for you.
Sincerely,
Is there a way in C# to guarantee that a method of a superclass will be automatically called by every subclass constructor?
Specifically, I am looking for a solution that only adds code to the superclass, so not "base(arguments)"
The only way to guarantee it is to make the call in the constructor of the base class. Since all subclasses must call a constructor of the base, your method of interest will be called as well:
class BaseClass {
public void MethodOfInterest() {
}
// By declaring a constructor explicitly, the default "0 argument"
// constructor is not automatically created for this type.
public BaseClass(string p) {
MethodOfInterest();
}
}
class DerivedClass : BaseClass {
// MethodOfInterest will be called as part
// of calling the DerivedClass constructor
public DerivedCLass(string p) : base(p) {
}
}
I have a set of classes where my base has a constructor that takes a configuration object and handles transferring the values to its properties.
abstract class A { public A(ObjType MyObj){} }
abstract class B : A {}
class C : A {}
class D : B {}
class E : B {}
Is it possible to implicitly call a non-default base constructor from child classes or would I need to explicitly implement the signature up the chain to do it via constructors?
abstract class A { public A(ObjType MyObj){} }
abstract class B : A { public A(ObjType MyObj) : base(MyObj){} }
class C : A { public A(ObjType MyObj) : base(MyObj){} }
class D : B { public A(ObjType MyObj) : base(MyObj){} }
class E : B { public A(ObjType MyObj) : base(MyObj){} }
If that is the case, is it better to just implement a method in the base then have my factory immediately call the method after creating the object?
Implicitly? No, constructors are not inherited. Your class may explicitly call it's parent's constructor. But if you want your class to have the same constructor signatures as the parent class's, you must implement them.
For example:
public class A
{
public A(int someNumber)
{
}
}
// This will not compile becase A doesn't have a default constructor and B
// doesn't inherit A's constructors.
public class B : A
{
}
To make this work you'd have to explicitly declare the constructors you want B to have, and have them call A's constructors explicitly (unless A has a default constructor of course).
public class B : A
{
public B(int someNumber) : base(someNumber)
{
}
}
No it's not possible to call a non-default base constructor implicitly, you have to make it explicit.
You need to explicitly implement it up the chain. Also, importantly, in your original code, you will not be able to call a new B(), since A does not have a default constructor, and B does not call A's constructor that has an arg.
My code is
public class Parent
{
public Parent(int i)
{
Console.WriteLine("parent");
}
}
public class Child : Parent
{
public Child(int i)
{
Console.WriteLine("child");
}
}
I am getting the error:
Parent does not contain a constructor that takes 0 arguments.
I understand the problem is that Parent has no constructor with 0 arguments. But my question is, why do we need a constructor with zero arguments? Why doesn't the code work without it?
Since you don't explicitly invoke a parent constructor as part of your child class constructor, there is an implicit call to a parameterless parent constructor inserted. That constructor does not exist, and so you get that error.
To correct the situation, you need to add an explicit call:
public Child(int i) : base(i)
{
Console.WriteLine("child");
}
Or, you can just add a parameterless parent constructor:
protected Parent() { }
You need to change your child's constructor to:
public child(int i) : base(i)
{
// etc...
}
You were getting the error because your parent class's constructor takes a parameter but you are not passing that parameter from the child to the parent.
Constructors are not inherited in C#, you have to chain them manually.
You need to change the constructor of the child class to this:
public child(int i) : base(i)
{
Console.WriteLine("child");
}
The part : base(i) means that the constructor of the base class with one int parameter should be used. If this is missing, you are implicitly telling the compiler to use the default constructor without parameters. Because no such constructor exists in the base class it is giving you this error.
The compiler cannot guess what should be passed for the base constructor argument. You have to do it explicitly:
public class child : parent {
public child(int i) : base(i) {
Console.WriteLine("child");
}
}
You can use a constructor with no parameters in your Parent class :
public parent() { }
By default compiler tries to call parameterless constructor of base class.
In case if the base class doesn't have a parameterless constructor, you have to explicitly call it yourself:
public child(int i) : base(i){
Console.WriteLine("child");}
Ref : Constructor calling hierarchy during inheritance
I've got a (poorly written) base class that I want to wrap in a proxy object. The base class resembles the following:
public class BaseClass : SomeOtherBase
{
public BaseClass() {}
public BaseClass(int someValue) {}
//...more code, not important here
}
and, my proxy resembles:
public BaseClassProxy : BaseClass
{
public BaseClassProxy(bool fakeOut){}
}
Without the "fakeOut" constructor, the base constructor is expected to be called. However, with it, I expected it to not be called. Either way, I either need a way to not call any base class constructors, or some other way to effectively proxy this (evil) class.
There is a way to create an object without calling any instance constructors.
Before you proceed, be very sure you want to do it this way. 99% of the time this is the wrong solution.
This is how you do it:
FormatterServices.GetUninitializedObject(typeof(MyClass));
Call it in place of the object's constructor. It will create and return you an instance without calling any constructors or field initializers.
When you deserialize an object in WCF, it uses this method to create the object. When this happens, constructors and even field initializers are not run.
If you do not explicitly call any constructor in the base class, the parameterless constructor will be called implicitly. There's no way around it, you cannot instantiate a class without a constructor being called.
At least 1 ctor has to be called. The only way around it I see is containment. Have the class inside or referencing the other class.
I don't believe you can get around calling the constructor. But you could do something like this:
public class BaseClass : SomeOtherBase
{
public BaseClass() {}
protected virtual void Setup()
{
}
}
public BaseClassProxy : BaseClass
{
bool _fakeOut;
protected BaseClassProxy(bool fakeOut)
{
_fakeOut = fakeOut;
Setup();
}
public override void Setup()
{
if(_fakeOut)
{
base.Setup();
}
//Your other constructor code
}
}
If what you want is to not call either of the two base class constructors, this cannot be done.
C# class constructors must call base class constructors. If you don't call one explicitly, base( ) is implied. In your example, if you do not specify which base class constructor to call, it is the same as:
public BaseClassProxy : BaseClass
{
public BaseClassProxy() : base() { }
}
If you prefer to use the other base class constructor, you can use:
public BaseClassProxy : BaseClass
{
public BaseClassProxy() : base(someIntValue) { }
}
Either way, one of the two will be called, explicitly or implicitly.
When you create a BaseClassProxy object it NEEDS to create a instance of it's base class, so you need to call the base class constructor, what you can doo is choose wich one to call, like:
public BaseClassProxy (bool fakeOut) : base (10) {}
To call the second constructor instead of the first one
I am affraid that not base calling constructor isn't option.
I ended up doing something like this:
public class BaseClassProxy : BaseClass
{
public BaseClass BaseClass { get; private set; }
public virtual int MethodINeedToOverride(){}
public virtual string PropertyINeedToOverride() { get; protected set; }
}
This got me around some of the bad practices of the base class.
constructors are public by nature. do not use a constructor and use another for construction and make it private.so you would create an instance with no paramtersand call that function for constructing your object instance.
All right, here is an ugly solution to the problem of one class inheriting the constructors of another class that I didn't want to allow some of them to work. I was hoping to avoid using this in my class but here it is:
Here is my class constructor:
public MyClass();
{
throw new Exception("Error: Must call constructor with parameters.");
}
OK now you were warned that it was ugly. No complaints please!
I wanted to force at least the minimal parameters from my main constructor without it allowing the inherited base constructor with no parameters.
I also believe that if you create a constructor and do not put the : base() after it that it will not call the base class constructor. And if you create constructors for all of the ones in the base class and provide the same exact parameters for them in the main class, that it will not pass through. But this can be tedious if you have a lot of constructors in the base class!
It is possible to create an object without calling the parameterless constructor (see answer above). But I use code like this to create a base class and an inherited class, in which I can choose whether to execute the base class's init.
public class MyClass_Base
{
public MyClass_Base()
{
/// Don't call the InitClass() when the object is inherited
/// !!! CAUTION: The inherited constructor must call InitClass() itself when init is needed !!!
if (this.GetType().IsSubclassOf(typeof(MyClass_Base)) == false)
{
this.InitClass();
}
}
protected void InitClass()
{
// The init stuff
}
}
public class MyClass : MyClass_Base
{
public MyClass(bool callBaseClassInit)
{
if(callBaseClassInit == true)
base.InitClass();
}
}
Here is my solution to the problem
using System;
public class Program
{
public static void Main()
{
Console.WriteLine(new Child().Test);
}
public class Child : Parent {
public Child() : base(false) {
//No Parent Constructor called
}
}
public class Parent {
public int Test {get;set;}
public Parent()
{
Test = 5;
}
public Parent(bool NoBase){
//Don't do anything
}
}
}
A simple elegant solution. You can change it according to your need.
Another simple solution from me:
class parent
{
public parent()
{
//code for all children
if (this.GetType() == typeof(child1))
{
//code only for objects of class "child1"
}
else
{
//code for objects of other child classes
}
}
}
class child1 : parent
{
public child1()
{}
}
// class child2: parent ... child3 : parent ... e.t.c