Base Classes constructor being hit without calling it? - c#

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

Related

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.

Automatically call superclass method in constructor

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) {
}
}

Why can't we use a constructor with parameter in derived classes

Why is this not possible?
I get the following compiler-error when instantiating "DerivedClass" with a constructor-parameter:
'GenericParameterizedConstructor.DerivedClass' does not contain a constructor that takes 1 argument
But calling a very similar method works.
Why?
class Program
{
static void Main(string[] args)
{
// This one produces a compile error
// DerivedClass cls = new DerivedClass("Some value");
// This one works;
DerivedClass cls2 = new DerivedClass();
cls2.SomeMethod("Some value");
}
}
public class BaseClass<T>
{
internal T Value;
public BaseClass()
{
}
public BaseClass(T value)
{
this.Value = value;
}
public void SomeMethod(T value)
{
this.Value = value;
}
}
public class DerivedClass : BaseClass<String>
{
}
Constructors aren't inherited - it's as simple as that. DerivedClass contains a single constructor - the public parameterless constructor provided by default by the compiler, because you haven't specified any constructors.
Note that this has nothing to do with generics. You'd see the same thing if BaseClass weren't generic.
It's easy to provide constructors for DerivedClass though:
public class DerivedClass : BaseClass<String>
{
public DerivedClass() : base()
{
}
public DerivedClass(string value) : base(value)
{
}
}
The deriving class needs to expose the constructor
public class DerivedClass : BaseClass<String>
{
public DerivedClass(string str) :base(str) {}
}
It would sometimes be helpful if there a way of instructing the compiler to automatically generate for a particular derived class constructors which precisely mimic and wrap all those of the base class. Having such behavior occur by default, however, would be problematic. Many derived classes expect that some of their code will be called whenever an instance of their type is created. Suppose a parent type had two constructors:
parentType(int foo) {...}
parentType(string foo) {...}
and a derived type had one:
derivedType(string foo) {...}
What should be the effect of new derivedType(7);? The compiler would know how to create a new baseType(7);, but if it created a new "blank" derivedType object and then simply called the parent-type constructor, the result would be a derivedType object which had never run any of derivedType's construction code. While some classes wouldn't have any problem with that (and for such classes, the earlier-mentioned hypothetical feature would be helpful), a lot of classes would.
Incidentally, a somewhat-related issue occurs with protected constructors. In some .net languages including at least the current version of C#, if non-abstract type Foo defines a protected constructor, that constructor may only be used to create instances of derived types. In other languages, including the current vb.net, it's possible for code within a derived type to call a protected constructor of the base type to create a new base-type instance.

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.

calling base constructor passing in a value

public DerivedClass(string x) : base(x)
{
x="blah";
}
will this code call the base constructor with a value of x as "blah"?
The base call is always done first, but you can make it call a static method. For example:
public Constructor(string x) : base(Foo(x))
{
// stuff
}
private static string Foo(string y)
{
return y + "Foo!";
}
Now if you call
new Constructor("Hello ");
then the base constructor will be called with "Hello Foo!".
Note that you cannot call instance methods on the instance being constructed, as it's not "ready" yet.
No, base call we be performed before executing the constructor body:
//pseudocode (invalid C#):
public Constructor(string x) {
base(x);
x = "blah";
}
No, the base constructor is always called before the current constructor.
No, it will call it with the value passed into the derived class constructor. Base class constructor is always called (explicitly or implicitly) prior to executing the body of the derived class constructor.
No, It won't. The base constructor will be passed the string in x before the execution of DerivedClass constructor. This may work:
public DerivedClass(string x) : base("Blah")
{ }
I'm not sure about that but you should be able to call any method / getter when calling the base constructor, like that:
public DerivedClass(DateTime x) : base(DateTime.Now)
{ }

Categories

Resources