Base class field initialization in derived class - c#

1) If I define a field in a base class like
myType myField = new MyField();
Will this field be always initialized in a derived class?
2) If I initialize this field through base class default (parameterless) constructor will it be initialized in a derived class?
Assuming I do not call any :base() constructors from derived type.
My point is to instantiate field with default value only in base class and provide overridden initialization in derived classes.

Yes, fields will always be initialized. If you don't explicitly chain to any other constructors, you'll chain to base() implicitly. You'll always end up chaining right up the type hierarchy until you hit Object.
My point is to instantiate property with default value only in base class and provide overridden initialization in derived classes.
Then I suggest in the base class, you have two constructors, one of them possibly protected:
public class BaseClass
{
private MyType myField;
protected BaseClass(MyType myField)
{
this.myField = myField;
}
public BaseClass() : this(new MyType())
{
}
}
Then constructors from your derived types can chain to either constructor, as appropriate... and you don't end up creating an instance of MyType when you don't need to.

Related

Executing constructor from Parent class to Child class

In what situations should I execute a constructor of the parent class for a child class? And why use the "base" reserved word?
Exemple:
The constructor of the base class is always called. Or more exact, one constructor of the base class. If you don't specify which one (by using the base reserved word), the default constructor of the base class is called (that means the one with no arguments). If the base class has no constructor without arguments, a compiler error occurs. With the base keyword, you specify that you want to call a certain constructor. Here are some simple examples:
public class Base
{
private int _a;
public Base() // default ctor
{_a = 0;}
public Base(int a) // a ctor with an argument
{_a = a;}
}
public class Derived : Base
{
public Derived() : base(2) // call the ctor with argument "2"
{}
public Derived(bool b) // uses the ctor without argument of the base class (_a will stay 0)
{
}
}
The keyword base here is used as a generic placeholder for the name of the base class. The only other word syntactically allowed there would be this (if you want to call a constructor of the same class)
If you not use :base word for child constructor.
Default constructor of parent will be executed.
If you have some basic construnctor in base class and you have some fields in it and want to fill it using basic constructor you should use base keyword.

Inheriting constructor with single optional argument

I have a set of classes that inherit from a base...
public abstract class BaseClass
{
public BaseClass()
{
// ...
}
}
public abstract class BaseMessageClass : BaseClass
{
// ...
}
public SpecificMessageClass : BaseMessageClass
{
// ...
}
Instantiating an object like this works:
SpecificMessageClass myMessage = new SpecificMessageClass();
However, I need to change all constructors to have an optional string parameter, like this:
public abstract class BaseClass
{
public BaseClass(string optParam="whatever")
{
// ...
}
}
Now, when I try and instantiate the object with the optional argument:
SpecificMessageClass myMessage = new SpecificMessageClass("coolstring");
I get the error:
'SpecificMessageClass' does not contain a constructor that takes 1 arguments"
Is there ANY way to do this without explicitly declaring the constructors in each level of inherited class?
No.
But given that you want to inherit, I'm guessing you want the same logic to apply at all levels on some inherited field or property. If so, the closest you can get is to add a factory method like a Create<T>(string optParam="whatever") on the base class like the following:
public class BaseClass
{
public static T Create<T>(string optParam="whatever") where T : BaseClass
{
var t = new T(); //which invokes the paramterless constructor
((BaseClass)t).SomePropertyOrFieldInheritedFromTheBaseClass = optParam; //and then modifies the object however your BaseClass constructor was going to.
return t;
}
}
That would allow all implementers of the class to implement the BaseClass and get the same effect as having the optional parameter constructor.
By the way, I didn't test the above code, so you might need to tweak it slightly. But hopefully it gives the idea.
I think that's probably the closest you can get.
Constructors are special methods. If your class specifies no constructors, it will have a no-args constructor that inherits from the parent's no-args constructor. As soon as you specify a single constructor, you do not automatically get any of the parent's constructors for free. You must declare each different constructor you need.

Create an instance of an inherited class from abstract base class constructor

Using reflection, is it possible to create an instance of a type that inherits from an abstract base class using the abstract base class' constructor? That is, without the inheriting class having a constructor of its own? Somewhat like below, but it throws an error because you cannot create an instance of an abstract class, of course:
abstract class PersonBase
{
string Name;
public PersonBase(string _name) { Name = _name; }
}
class Person : PersonBase
{
}
public static T GetPerson<T>(string name) where T : PersonBase, new()
{
ConstructorInfo info = typeof(T).BaseType.GetConstructor(new Type[]
{ typeof(string) });
object result = info.Invoke(new object[] { name });
return (T)result;
}
You can make this work by doing new T { (assign properties here) } but of course thats not a constructor, and the properties would have to be public, etc.
The only place it's legal to call an abstract class constructor - whether by reflection or not - is within the constructor of a derived class. So no - as you say, you'd be creating an instance of the abstract type, instead of the concrete type. Imagine if the abstract class had an abstract method, and you called it on whatever the constructor returned - what would that do?
If you can give us more information about what you're trying to achieve, we may be able to help you more.
(Your current example wouldn't even compile, as the default Person constructor doesn't have a parameterless base class constructor to call.)

Parameterized abstract class constructor

I have a class like below
public abstract class ABC
{
int _a;
public ABC(int a)
{
_a = a;
}
public abstract void computeA();
};
Is it mandatory for the derived class to supply the parameters for the base/abstract class constructor? Is there any way to initialize the derived class without supplying the parameters?
Thanks in advance.
Yes, you have to supply an argument to the base class constructor.
Of course, the derived class may have a parameterless constructor - it can call the base class constructor any way it wants. For example:
public class Foo : ABC
{
// Always pass 123 to the base class constructor
public Foo() : base(123)
{
}
}
So you don't necessarily need to pass any information to the derived class constructor, but the derived class constructor must pass information to the base class constructor, if that only exposes a parameterized constructor.
(Note that in real code Foo would also have to override computeA(), but that's irrelevant to the constructor part of the question, so I left it out of the sample.)
You can create a default constructor in a derived class that does not need parameters and the derived class will supply default values, but you cannot remove the requirement entirely. It is a manadatory condition of the base class to have some sort of value.
public MyDerivedClass : ABC
{
public MyDerivedClass()
: base(123) // hard wired default value for the base class
{
// Other things the constructor needs to do.
}
public override void computeA()
{
// Concrete definition for this method.
}
}
Add a default constructor to the base class and call the other constructor providing an initial values for its parameters:
public abstract class ABC
{
int _a;
public ABC(int a)
{
_a = a;
}
public ABC() : this(0) {}
}
It doesn't have much to do with the fact that the base class is abstract.
Because you've declared a public constructor that has 1 parameter, the compiler removes the basic empty constructor.
So, if you want to create an instance of that class, you have to pass a parameter.
When you derive from such a class, a parameter must be passed to the base class for it o construct.

What is the code : base()

What is the purpose of base() in the following code?
class mytextbox : TextBox
{
public mytextbox() : base()
{
this.Text = "stack";
}
}
Why At design time messages are displayed ؟
my code :
class Class1:TextBox
{
public Class1()
{
this.Resize += new EventHandler(Class1_Resize);
}
void Class1_Resize(object sender, EventArgs e)
{
MessageBox.Show("Resize");
}
}
base() in your code is a call to the parameterless constructor of the base-class ofmyTextBox, which happens to beTextBox. Note that this base constructor will execute before the execution of the body of the constructor in the derived class.
Every class's constructor must eventually call one of its base class's constructors, either directly or through chained constructors in the same class. Consequently, there is always an implicit / explicit base(...) or explicit this(...) call on every constructor declaration. If it is omitted, there an implicit call to base(), i.e. the parameterless constructor of the base class (this means that the call tobase()in your example is redundant). Whether such a declaration compiles or not depends on whether there exists such an accessible constructor in the base class.
EDIT:
Two trivial points:
The root of the class-hierarchy does not have a base class, so this rule does not apply to System.Object's only constructor.
The first sentence should read: "every non-System.Object class's constructor that completes successfully must eventually call one of its base class's constructors." Here is a 'turtles all the way down' example where the base class's contructor is never called: instantiating an object of such a class will obviously overflow the execution-stack.
// Contains implicit public parameterless constructor
public class Base { }
// Does not contain a constructor with either an explicit or implicit call to base()
public class Derived : Base
{
public Derived(int a)
: this() { }
public Derived()
: this(42) { }
static void Main()
{
new Derived(); //StackOverflowException
}
}
No idea, it is unnecessary. A constructor always calls the base class constructor automatically without you having to write it explicitly. But that's what it means. You'd have to write it if you don't want to call the parameterless constructor but one that takes an argument.

Categories

Resources