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) {
}
}
Related
Given the code:
public class A
{
public A()
{
throw new Exception();
}
}
public class B : A
{
public B(int i)
{
}
}
Then running the line:
var x = new B(2);
I would never expect A's constructor to get hit (unless I added base()) to the end of B's constructor declaration.
Oddly it seems to be getting hit (and throwing the exception). Is this default behavior? This has caught me out as I fully never expected A's constructor to be hit
If you don't include any base(..) or this(..), it does the same thing as if you had base(). From the C# spec:
If an instance constructor has no constructor initializer, a constructor initializer of the form base() is implicitly provided. Thus, an instance constructor declaration of the form
C(...) {...}
is exactly equivalent to
C(...): base() {...}
You might've been looking to make A an abstract class, so that you cannot directly create an instance of A.
public abstract class A
{
}
public class B : A
{
public B(int i)
{
}
}
public static void Main()
{
// A a = new A(); // doesn't compile
A a = new B(2); // valid
}
But within B class inherited by A class.so when you create on B instance ,automatically initiate the A instance as well.This is the default behavior in OOP concept.
This is the default behaviour. Constructors run in order from base class first to inherited class last. When you write base() then you can pass some value directly to base constructor
for eg
public class B : A
{
public B(int i): base(i)
{
}
}
As your commentors have mentioned, this is the default C# behavior. A constructor on each base class MUST be called.
If your rule is that ClassA should never be constructed (only child classes), declare ClassA as abstract
public abstract class A {}
With that syntax, it will be a compile-time error if you attempt to construct an A (but B will be ok), so you can remove the throw in A's constructor.
That's expected: if you don't explicitly specify a different overload of a constructor, it will always be invoked by default. And even if you do specify a different overload to call, it will also propagate to its base class' constructor until it reaches the root Object() constructor.
Note that this also means that if you have a different constructor overload in a single class, instantiating the object through the overloaded constructor will not call the parameterless constructor of that same class, but instead the parameterless constructor of the base class (in this case, Object()):
public class A
{
public A()
{
throw new Exception();
}
public A(int i)
{
// this will not call the A(), but the base Object() constructor
}
}
var a = new A(5); // no exception thrown
Well, originally I had a couple of constants (like MAX_SPEED) with different values in every of the derived classes. The idea was to use those values in some methods of the base class. That's when I realized that I cannot do that with constants, so I created read-only properties.
I need a method to assign those values to private fields at the moment of the instantiation, preferably in the base class. But first I have to assing the original values in derived classes. Since those are properties, I couldn't find a way to initialize them while defining, so the only way to do that is in the derived constructors.
That's where the problem comes: values are initialized after their assigning to private fields in the base class. The solution I get away with is to create a virtual method and to do assigning there.
Is there a way to call a base constructor from derived class so that the code from derived constructor will be invoked first?
class BaseClass
{
public BaseClass()
{
System.Console.WriteLine("This should be shown after");
}
}
class DerivedClass : BaseClass
{
public DerivedClass() : base()
{
System.Console.WriteLine("This should be shown first");
}
}
Of course in the example it would work the other way around. Is there a solution?
No. The base class constructor is always executed before the body of the derived class constructor. However:
Any instance variable initializers in the derived class are executed before the base class constructor
The base class constructor can execute virtual methods which can be overridden in the derived class. This is almost always a bad idea though. (All kinds of normal preconditions are invalid at this point. You can observe readonly variables which haven't been set yet because they'll be set in the constructor body, for example. Ick.)
To demonstrate both of these:
using System;
class BaseClass
{
public BaseClass()
{
VirtualMethod();
Console.WriteLine("BaseClass ctor body");
}
public virtual void VirtualMethod()
{
Console.WriteLine("BaseClass.VirtualMethod");
}
}
class DerivedClass : BaseClass
{
int ignored = ExecuteSomeCode();
public DerivedClass() : base()
{
Console.WriteLine("DerivedClass ctor body");
}
static int ExecuteSomeCode()
{
Console.WriteLine("Method called from initializer");
return 5;
}
public override void VirtualMethod()
{
Console.WriteLine("DerivedClass.VirtualMethod");
}
}
class Test
{
static void Main()
{
new DerivedClass();
}
}
Output:
Method called from initializer
DerivedClass.VirtualMethod
BaseClass ctor body
DerivedClass ctor body
Additionally, if your base class constructor takes a parameter, then you can execute some code in the derived class in order to provide an argument:
DerivedClass() : base(SomeStaticMethod())
All of these are fairly smelly though. What's your specific situation?
No, you can't do that. Base classes are always initialized first. However, you can do something like this:
class BaseClass
{
public BaseClass()
{
this.Initialize();
}
protected virtual void Initialize()
{
System.Console.WriteLine("This should be shown after");
}
}
class DerivedClass : BaseClass
{
public DerivedClass() : base()
{
}
protected override void Initialize()
{
System.Console.WriteLine("This should be shown first");
base.Initialize();
}
}
One more option is to make child class constructor as static , so that it executes first than parent class constructor. but it not preferable it violates the oop design
How can I call base class' constructor after I've called my own constructor?
The problem is, base class' constructor calls an abstract method (overridden in sub class), which needs to access variable x, initialized in sub class' constructor?
Short example code:
abstract class BaseClass
{
protected string my_string;
protected abstract void DoStuff();
public BaseClass()
{
this.DoStuff();
}
}
class SubClass : BaseClass
{
private TextBox tb;
public SubClass()
: base()
{
this.my_string = "Short sentence.";
}
protected override void DoStuff()
{
// This gets called from base class' constructor
// before sub class' constructor inits my_string
tb.Text = this.my_string;
}
}
Edit: Based on answers, it obviously is not possible. Is there an automated way to call this.DoStuff(); on every object of SubClass once they're created? Of course I could just add this.DoStuff(); after all the other lines in sub class' constructor, but having around 100 of these classes, it feels stupid. Any other solution, or should I use the manual one?
You can't.
Also, you generally shouldn't call virtual methods in a constructor. See this answer.
Depending on your actual code and not the simple example you wrote, you could pass values as parameters of the base constructor and the DoStuff method. For example:
abstract class BaseClass
{
private string my_string;
protected abstract void DoStuff(string myString);
public BaseClass(string myString)
{
this.my_string = myString;
this.DoStuff(this.my_string);
}
}
class SubClass : BaseClass
{
private TextBox tb;
public SubClass()
: base("Short sentence.")
{
}
protected override void DoStuff(string myString)
{
tb.Text = myString;
}
}
If it's not possible with your actual code, then writing multiple DoStuff() will do the job. Also remember to seal your SubClass class so nobody else will be able to introduce bugs by modifying the DoStuff method another time.
I would not call an abstract method in the constructor as it can happen that the constructor for the instance that invokes the method has not executed
When a virtual method is called, the actual type that executes the method is not selected until run time. When a constructor calls a virtual method, it is possible that the constructor for the instance that invokes the method has not executed.
To fix a violation of this rule, do not call a type's virtual methods from within the type's constructors.
http://msdn.microsoft.com/en-us/library/ms182331%28v=vs.80%29.aspx
You can't do it like that. But you can put your initiation code of the master class into a separate initialize method. You then can call that method in your specific constructor >after the constructor code.
Is there a reason you can't construct a class before its constructor actually runs? It requires a greater level of responsibility on how the derived class is created and probably not a best practice, but it appears to work.
abstract class BaseClass {
protected string my_string;
protected abstract void DoStuff();
public BaseClass() {
this.DoStuff();
}
}
class SubClass: BaseClass {
TextBox tb;
bool Constructed = false;
void Constructor() {
if (!Constructed) {
Constructed = true;
this.my_string = "Short sentence.";
}
}
public SubClass()
: base() {
Constructor();
}
protected override void DoStuff() {
Constructor();
// This gets called from base class' constructor
// before sub class' constructor inits my_string
tb.Text = this.my_string;
}
}
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.
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