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.
Related
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
}
}
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) { }
}
I am confuse on what is the default constructor access modifier and what does this MSDN statemtn says
If the direct base class does not have an accessible parameterless instance constructor, a compile-time error occurs.
Because when i applied this with a test program it fails. I can make an object or class that is inheriting another class thogh there is no exteranal parameerless constructor defined.
class A
{
}
class B : A
{
}
class C
{
public void main()
{
B objB = new B();// as per MSDN here should be the compile time error.
}
}
[Source]
If the direct base class does not have an accessible parameterless
instance constructor, a compile-time error occurs.
If a constructor is not defined for a class, the compiler will automatically generate a public default constructor.
If a class contains no instance constructor declarations, a default
instance constructor is automatically provided. That default
constructor simply invokes the parameterless constructor of the direct
base class. If the direct base class does not have an accessible
parameterless instance constructor, a compile-time error occurs. If
the class is abstract then the declared accessibility for the default
constructor is protected. Otherwise, the declared accessibility for
the default constructor is public.
In your example, all the classes A, B, C has been created with a default internal parameterless constructor.
Since both classes are in the same assembly and are internal with internal constructors by default you are not getting a compilation error. But if you declare a non-accessible constructor (e.g. private or protected) in your class B you will get a compilation error in your example.
The compiler creates parameterless constructor if you don't create one yourself, so as per the MSDN page, your example actually ends up looking like this;
class A
{
public A(): base() {}
}
class B : A
{
public B(): base() {}
}
Your call to new B() will ultimately end up calling A's constructor. However, if you created an explicit constructor for A which is private;
class A
{
private A() {}
}
class B : A
{
}
Then this translates to;
class A
{
private A() {}
}
class B : A
{
public B(): base() {}
}
Which will fail to compile with an error about A's constructor being inaccessible.
If a constructor is not defined for a class, the compiler will automatically generate a public default constructor.
However, if there is a constructor defined that limits the access, then the compiler will throw.
for example, this should throw an exception:
class A
{
private A() {}
}
class B : A
{
}
From Using Constructors
Unless the class is static, classes without constructors are
given a public default constructor by the C# compiler in order to
enable class instantiation.
I'm having a slight issue with some inheritance.
In my base class I have the following constructor:
public Camera(string n)
{
name = n;
}
Then in my child class I have the following constructor:
public StereoCameras(string n)
{
name = n;
}
How ever, my child class complains it does not contain a constructor that takes 0 arguments. I'm fairly new to using inheritance like this, and I thought I had set up my childs constructor properly.
Is there something I'm missing?
You will need to invoke the base constructor:
public StereoCameras(string n) : base(n)
{
}
Then the assignment in the derived class is redundant.
Your child class constructor call is equivalent to:
public StereoCameras(string n) : base()
since you have not defined any parameter less constructor in your base class, hence the error. Base class's parameter less constructor is called implicitly (if none is called using base keyword)
See: Using Constructors (C# Programming Guide) - MSDN
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
To come over the problem you can either declare a parameter less constructor in base class or call the defined constructor explictily like:
public StereoCameras(string n) : base(n)
Also from the same link
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.
Use
public StereoCameras(string n) : base(n)
{
}
When a class is instantiated the constructor of the base-class is always invoked before the constructor of the derived class. If the base class does not contain a default constructor you must explicitly define how to call the constructor of the base class.
In your case this would be (note the base call)
public StereoCameras(string n)
: base(n)
{
}
Just add a constructor without any parameter to the base class. This will solve your issue.
public Camera()
{
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can’t I create an abstract constructor on an abstract C# class?
Why I can't declare abstract an constructor of my class like this:
public abstract class MyClass {
public abstract MyClass(int param);
}
Constructors are only applicable to the class in which they are defined, that is, they are not inherited. Base class constructors are used (you have to call one of them, even if only calling the default one automatically) but not overridden by deriving classes. You can define a constructor on an abstract base class -- it can't be used directly, but can be invoked by deriving classes. What you can't do is force a derived class to implement a specific constructor signature.
It is perfectly reasonable to have a constructor defined, typically as protected, in order to define some common set up code for all derived classes. This is especially true, perhaps, when the abstract class provides some other default behavior which relies on this set up. For example:
public abstract class Foo
{
public string Name { get; private set; }
protected Foo( string name )
{
this.Name = name;
}
}
public class Bar : Foo
{
public Bar() : base("bar")
{
...
}
}
You can't declare it abstract, but you can have a constructor on your abstract class; just remove the word abstract and provide a body for it.
Constructors are closer to static methods rather than "regular" methods. Like static methods, they can be overloaded, but not overriden. That is, they are not inherited but can be redefined.
public BaseClass
{
public BaseClass( String s ) { ... }
public static void doIt ( String s ) { ... }
}
public SubClass extends BaseClass
{
public SubClass( String s ) { ... }
public static void doIt ( String s ) { ... }
}
public SubClass2 extends BaseClass
{
}
new SubClass( "hello" );
SubClass.doIt( "hello" );
new SubClass2( "hello" ); // NOK
SubClass2.doIt( "hello" ); // NOK
Constructors and static methods are never dispatched dynamically (virtually) -- You always know the concrete type you instantiate or the concrete class of the static method. That's why it makes no sense to have abstract constructor and abstract static method. That's why you can also not specify constructor and static method in interfaces.
You can even think of constructor as static factory method (and see the corresponding pattern):
MyClass obj = new MyClass(); // the way it is
MyClass obj = MyClass.new(); // think of it like this
The only case I see where it would make sense to define abstract constructor or abstract static method would be if reflection is used. In this case, you could ensure that all subclass would redefine the corresponding static method or constructor. But reflection is another topic...
Note: in languages such as Smalltalk where classes are regular objects, you can override static method and have abstract constructor. But it doesn't apply to Java because classes are not "regular" objects even if you can get them with reflection.
Abstract implies virtual. A non-default constructor can never be called polymorphically, so virtual and abstract are not allowed on constructors.
IF in a future version of C#, generics are enhanced to allow calling non-default constructors through a generic type parameter, then polymorphic calls to constructors would be possible and virtual and abstract constructors might be added as well.
What wrong with this:
public abstract class MyClass {
protected MyClass(int param)
{
}
}
In this case you oblige all derived classes to call base class constructor.
Because abstract constructors are not supported.
But a abstract class can have a constructor.
A constructor is not an ordinary method. It has a special purpose, and so is restricted to language features that make sense for that purpose. See also: Why do constructors not return values?
By definition, the class can't be instantiated directly, so in a sense, it already is abstract.