How to avoid calling the base class constructor - c#

I'm just after a little advice on how to best organise the inheritance here. I have a class (below) that needs to use most of, and overide some of, the classes in the base ExportData class:
public class ExtendedExportData : ExportData
{
private tData _Data;
private ResStrings _diaStrings;
public ExtendedExportData(tData Data, ResStrings diaStrings)
: base(tData, diaStrings)
{
_tData = Data;
_diaStrings = diaStrings;
}
}
What isn't neccesary in this case is having to call the base constructor as none of the base class methods used in the class above require that initialisation, the constructor is only neccesary when creating an instance of the base class directly for other (verbose) purposes.
If i remove the base constructor i get an error on the sub-class constructor saying the base constructor doesn't take 0 arguments. How can i avoid this?
Here's the base class:
public class ExportData
{
private tData _Data;
private ResStrings _diaStrings;
public ExportLines(tData Data, ResStrings diaStrings)
{
_Data = Data;
_diaStrings = diaStrings;
}
}
Thanks in advance.

A constructor of the base class is always used - but when the base class has no explicitly defined constructor, C# will generate a public parameterless constructor automatically.
Similarly, if you don't explicitly mention : base(...) in your derived class, C# assumes you want to use the parameterless constructor of the base class.
As soon as you define a constructor, the parameterless constructor is not automatically generated anymore, and so you have to call : base(...).
You can easily change this by adding such a constructor to the base class:
public class ExportData
{
protected ExportData()
{
}
}
By making this constructor protected, only classes that inherit from ExportData can use this constructor, and they no longer have to include : base(...).

You can always have a parameterless constructor in the base class that does all the initialising it needs to i.e.:
public ExportData()
{
//Initialising here
}
And then in your example just call base() i.e.
public ExtendedExportData(tData Data, ResStrings diaStrings)
: base()

Couldn't you just create an empty constructor (public ExportData(){}) in ExportData class ?
Else you could do something like here.

I know that this is old question but for future similar problem solution finders I would write something else.
If I undersand this question properly there is more elegant and common solution. Just make your base class abstract. You can still call base constructor during inheritance.
More information can be found here:
Constructor of an abstract class in C#

The error is because the base class always has to be instantiated and your base class doesn't have a default constructor.
If you have functionality in your base class that's not needed in the base class review your inheritance architecture.

Related

Abstract class with constructor, force inherited class to call it

I have an abstract class with constructor XYZ(string name).
Also I have a class that inherits from that abstract class.
How to force inherited class to call base(string name)?
Now I can use new Inherited() and it will not call base constructor. I want to force user to implement default constructor in inherited class.
A class without an explicit constructor has a parameterless constructor. In the other hand, if you implement a constructor with parameters and no paramterless constructor, your class won't be instantiable without arguments.
In other words:
public abstract class A
{
public A(string x)
{
}
}
public class B : A
{
// If you don't add ": base(x)"
// your code won't compile, because A has a
// constructor with parameters!
public B(string x) : base(x)
{
}
}
That is, if A has a parameterless constructor (or no explicit constructor), B will automatically call the base constructor. You don't need to code any further stuff here.
Otherwise, if your base class has a parameterless constructor and a constructor with parameters, you can't force a derived class to automatically call a constructor excepting the default one (i.e. the so-called parameterless constructor).
Workaround
Well, there's no special workaround here, but be aware C# supports optional parameters in both constructors and methods.
If you want to be 100% sure derived classes will call a concrete base constructor, you can implement your base class using a single parameterless constructor with optional parameters and use this instead of constructor overloading:
public class A
{
public A(string x = "hello world") // or just string x = null
{
}
}
Now if a B class derived A, B will always call A's base constructor, since x is optional and it has a default value.
How to force inherited class to call base(string name)
Make parameterless constructor in your abstract class private, or not add it at all. That's will force all derived classes to call the constructor you specified or there will be a compile error.
public abstract class BaseClass
{
protected BaseClass(string parameter)
{
}
}
public class DerivedClass : BaseClass
{
public DerivedClass()
{
}
}
Will end up with
'`Project.BaseClass`' does not contain a constructor that takes 0 arguments
You don't need to do anything. All derived class constructors must call a base class constructor (except for some particularly evil hacks, that you probably don't need to worry about). If none is explicitly specified in code, an implicit call to the base class's parameterless constructor is implied. If the base class has no parameterless constructor (as is the case if you add a constructor accepting a string and don't explicitly add a parameterless constructor), the class will not compile.
I have spent the last half hour or so experimenting once again with permutations of an abstract base class that has its default constructor marked as private and an overload that takes 4 parameters, and a derived class that has only the 4-parameter overload. Using the latest C# compiler (7.3), it is evident that in this situation:
The derived class must explicitly define the 4-parameter overload.
The overload in the derived class call to the 4-parameter overload must be explicit.
Base Class Constructor Signature
public OperatingParameterBase (
string pstrInternalName ,
string pstrDisplayName ,
T penmParameterType ,
U penmDefaultParameterSource )
Derived Class Constructor
internal OperatingParameter (
string pstrInternalName ,
string pstrDisplayName ,
T penmParameterType ,
U penmDefaultParameterSource )
: base (
pstrInternalName ,
pstrDisplayName ,
penmParameterType ,
penmDefaultParameterSource )
{
} // internal OperatingParameterExample constructor
I showed the whole constructor in the derived class to demonstrate that calling the base class constructor is its only absolute requirement. Since the work of the base constructor is irrelevant to this discussion, I left it out.

How can I avoid that the inherited class have to pass the base class constructor parameter

I have a base classe and an inheriting child class.
The base classes constructor accepts a parameter which I do not want to pass from my child constructor.
The parameter is a generic List<MyInterface>
Is that possible with C#?
at the moment my child class constructor looks like this:
public ChildClass() : base (new List<MyInterface>());
Is there a better way without having to new up the List?
If your base class constructor expects a parameter you have to pass that parameter from Child class.
You have two options.
Define a parameterless constructor in base class and then you can avoid passing your parameter. (Based on comment from #aevitas, if you are going to follow that approach, you may define the parameterless constructor as protected, as that will only be available to child classes)
Like:
public class BaseClass
{
public BaseClass() // or protected
{
//does nothing
}
}
and then call it like:
public ChildClass() : base ();
or just
public ChildClass() //Since base() would be called implicitly.
The other option is what you are using now, You can pass a new empty instance of your list or null as per your requirement.
You should also revisit your design. Not having a parameterless constructor in the base class implies that the class object requires that particular parameter to to work. Working around it is a code smell.
You could add a parameter-less constructor on your base class that creates the new List for you? Other than that, no, you have to do that.
You would have two constructors, like this:
public BaseClass(List<MyInterface> newList)
{
//blah blah blah
}
public BaseClass()
{
var myList = new List<MyInterface>();
}
Your base class must either
A) define a parameterless constructor so that you can invoke base()
Or
B) be ok with accepting a null value for the List<MyInterface> param
Like everyone has said you either need a parameterless constuctor in the base class or you need to pass the parameter. If the parameter is not needed at all in the child class then that could be a code smell.
If you only want your child class to have access to a parameterless constructor and no other you could make it protected.
public class BaseClass {
protected BaseClass() : this(new List<MyInterface>()) {
}
public BaseClass(List<MyInterface> newList)
{
//blah blah blah
}
}

Derived class explicit base constructor call

I am trying to learn C#. The below data is from a Microsoft C# help website.
I don't understand this statement, "If a base class does not offer a default constructor, the derived class must make an explicit call to a base constructor by using base."
I thought that if there is no default constructor for a class, C# will automatically assign default values to int, char or whatever is declared in a class. If a base class does not have a constructor and it has a child class, does the rule mentioned in the last sentence not apply? Please clarify.
In a derived class, if a base-class constructor is not called explicitly by using the base keyword, the default constructor, if there is one, is called implicitly. This means that the following constructor declarations are effectively the same:
C#
public Manager(int initialdata)
{
//Add further instructions here.
}
C#
public Manager(int initialdata)
: base()
{
//Add further instructions here.
}
If a base class does not offer a default constructor, the derived class must make an explicit call to a base constructor by using base.
If you do not define a constructor for a class:
public class DemoClass
{
public void SomeFunction() { }
}
C# will add a default (parameterless) constructor for you. In this case; nothing special needs to be done with derived classes, as they will use the provided default constructor. Of course, you can always define your own default (parameterless) constructor:
public class DemoClass
{
public void DemoClass() { }
public void SomeFunction() { }
}
Which still doesn't require anything special for derived classes, since they can still use it. If however, you define a parameterized constructor, without defining a default:
public class DemoClass
{
public void DemoClass(string argument) { }
public void SomeFunction() { }
}
Now there is no default (parameterless) constructor for derived classes to use; and you need to say which constructor to use with base:
public class DerivedClass : DemoClass
{
public DerivedClass() : base(String.Empty) { }
}

Is it good to have a constructor in abstract class?

Is it good to have a constructor in abstract class?
is it a good programming practice to create constructor of abstract class? since abstract classes can not be initialized, their child classes are initialized.
Following is my class structure.
public abstract class Scheduler
{
private Storyboard timer;
protected Scheduler()
{
// initialize the timer here.
timer = new Storyboard();
this.PollInterval = 60;
}
}
public class TaskScheduler : Scheduler
{
public TaskScheduler()
: base()
{
}
}
Yes, it's absolutely fine. Just because the constructor can only be called by derived classes doesn't mean it won't be useful. For example, you might have an abstract class which represents a named entity of some kind - it would make sense to take the name as a constructor parameter.
It would probably be worth making the constructor protected, to make it even more obvious that you can't just call it from elsewhere.
Note that there being a constructor (or multiple constructors) in an abstract class does force derived class constructors to go through it, but it doesn't force the derived classes to have the same constructor signatures. For example:
public abstract class NamedFoo
{
private readonly string name;
public string Name { get { return name; } }
protected NamedFoo(string name)
{
this.name = name;
}
}
public class DerivedFooWithConstantName
{
public DerivedFooWithConstantName() : base("constant name")
{
}
}
In this case the derived class constructor is "removing" a parameter (by providing a constant value as the argument to the abstract class constructor) but in other cases it could "add" parameters that it required, or have a mixture.
There is absolutely no reason not to have a constructor in an abstract base class.
The abstract class is initialized and works just like any other class. The abstract keywords only do the following:
It prevents the class itself to be instantiated directly. It can only be instantiated by instantiating an inherited class. This does not change the behavior of initialization compared to a not abstract base class;
It allows you to have abstract methods, properties and events in the class.
If you e.g. do not have abstract methods, properties or events, exactly the same result can be accomplished by making the constructor of a class protected (like you did). This also prevents the class to be instantiated directly. The behavior does not change however compared to an abstract class.
The primary difference then becomes the ability to declare methods, properties and events as abstract which you can only do when the class is marked abstract.
Having constructor in abstract class can be useful at times. This question is a duplicate, and dealt great deal in an related post. Even though it specifically reference JAVA, conceptually it applies to C# also.
Can an abstract class have a constructor?
Constructors on abstract types can be called only by derived types. Because public constructors create instances of a type, and you cannot create instances of an abstract type, an abstract type that has a public constructor is incorrectly designed. CA1012: Abstract types should not have constructors
Fix the violation by changing the accessibility of the constructor from public to protected.
Example:
namespace Sample
{
public abstract class Book
{
protected Book()
{
}
}
}

Abstract class constructor in C#

In c# we can't create an obeject of a abstact class or interface it means abstract class do not have any constructor, is it true ?
or if it have then what is it's purpose there?
As others have said, abstract classes usually have constructors (either explicitly or the default one created by the compiler) - and any derived class constructor will have to chain through the abstract class's constructor in the normal way. That's the important bit... suppose you have an abstract class which stores the name associated with an instance - because you always want a name, and you don't want to write the Name property in each concrete derived class. You might provide a constructor which takes that name and assigns it to a field... and then every subclass constructor would have to go through that constructor, so that you still knew you'd always have a name. If you want to know more about constructor chaining, read my article on it.
Here's an example of that:
public abstract class DemoBase
{
private readonly string name;
public string Name { get { return name; } }
protected DemoBase(string name)
{
this.name = name;
}
// Abstract members here, probably
}
public class FixedNameDemo : DemoBase
{
public FixedNameDemo()
: base ("Always the same name")
{
}
// Other stuff here
}
public class VariableNameDemo : DemoBase
{
public VariableNameDemo(string name)
: base(name)
{
}
// Other stuff here
}
To further answer your comment on BoltClock's answer, asbtract classes can't have private abstract methods, but they can have private constructors. Indeed, it's sometimes useful to have only private constructors in an abstract class, because it means the class can only be derived from within the program text of the same class. This allows you to create pseudo-enums:
public abstract class ArithmeticOperator
{
public static readonly ArithmeticOperator Plus = new PlusOperator();
public static readonly ArithmeticOperator Minus = new MinusOperator();
public abstract int Apply(int x, int y);
private ArithmeticOperator() {}
private class PlusOperator : ArithmeticOperator
{
public override int Apply(int x, int y)
{
return x + y;
}
}
private class MinusOperator : ArithmeticOperator
{
public override int Apply(int x, int y)
{
return x - y;
}
}
}
In this respect, an abstract private method/property could make sense - it could be accessed by the base class but provided by the derived classes within the same class's program text. However, it's prohibited by the specification. Usually, protected abstract members would solve the same problem - but not quite always.
Good question. Here's why Abstract classes need constructors even though they cannot be instantited.
In any Object oriented language like C#, object construction is an hierarchical process. Look at the code below. When you instantiate any object of type DerivedClass, it must construct the base object first before creating the object of typeof DerivedClass. Here the base class may or may not be an Abstract class. But even when you instantiate an object of a concrete type derived from an abstract class it will still need to call the constructor of the Base class before the object of DerivedClass type is created, hence you always need a constructor for Abstract class. If you have not added any constructor, C# compiler will automatically add a public parameterless constructor to the class in the generated MSIL.
public class BaseClass
{
public BaseClass()
{
Console.WriteLine("BaseClass constructor called..");
}
}
public class DerivedClass : BaseClass
{
public DerivedClass()
{
Console.WriteLine("DerivedClass constructor called..");
}
}
DerivedClass obj = new DerivedClass();
//Output
//BaseClass constructor called..
//DerivedClass constructor called..
PS: Assuming, If Abstract base classes
are not allowed to have constructors
because they need not be instantiated,
the whole fundamentals of the object
oriented programming will go on toss.
The idea behind Abstract types are to
represent objects that have some
features and behaviours but not
complete as whole to allow independant
existence.
No. it means that operator new is not allowed to create object from this type of class.
The purpose might be that are allocated/initialized some properties of class.
abstract usually leave some methods to implement.
Regarding the interface, this structure holds only the signatures of method, delegates or events. That may be implemented in class that use interface. You cant create a object.
Read about new
EDIT:
What is the purpose of constructor in abstract class ?
When one class inherit another class, the parent class of it had to be created first while object is crated. In class do not implement some special constructor always is used default one [className()]. When you override some method then the implementation of functionality is taken form class which override the method. This is why method used in constructor should never be virtual. Same logic for abstract class, such class can have a lot of functionality, and only one method that should be implemented by child class.
Abstract classes have constructors but you can't call them directly as you can't directly instantiate abstract classes.
To answer your comment, the concept of a private abstract method or property makes no sense, because private prevents anybody else from accessing it, and abstract prevents itself from accessing it. So there would essentially be no possible way to call it.
EDIT: see Jon Skeet's answer on private constructors. Private members of other kinds cannot exist in abstract classes, though.
Abstract classes do have constructors. When you create an instance of a derived class, its parent class' constructors are called. This applies to classes derived from abstract classes as well.

Categories