I have this code:
class Parent
{
public Parent(string someArg)
{
Console.WriteLine("Parent");
}
}
class Child : Parent
{
public Child(string someArg)
{
Console.WriteLine("Child");
}
}
which I then instantiate:
var child = new Child("something");
gets me an error. I know it has to do with the parent constructor, but I'm not sure why is this the case. Am I required to use base every time I have a constructor in the parent which is not parameter-less? Why?
The base class needs initialization just as well. Therefore, when the base class only has a constructor with an appetite for parameters, you will have to feed it.
In this case, if you are overriding everything the baseclass constructor does, you could let the baseclass have a second, parameterless, constructor. And if you'd like to make use of the logic in the baseclass constructor, you really have no choice but to call : base(string)
When you declare a class it has a default parameterless constructor. If you define your own construct then default one is gone. In your case you defined a constructor with a parameter.
When you create a new instance each class in inheritance hierarchy should be constructed. Base class has the only constructor with a string parameter which is not called in your code. The implicit parameterless constructor call cannot happen as well.
So that's why you should white:
public Child(string someArg) :base(someArg) { }
Or you can bring the parameterless constructor back in you code and do not use base:
public Parent() { }
Add this at base class to solve your problem.
public Parent() {}
or make it protected to use it just for child classes
protected Parent() {}
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've 2 classes: "RootClass", and "SubClass". SubClass is derived from RootClass. How do I make a constructor in RootClass, which can set values to fields found in SubClass?
I tried:
Set the subclass's value from the root's constructor, but it doesn't see the subclass's fields.
Create a constructor in SubClass, that doesn't seem to happen. Also tried setting the constructor in root to virtual, so the sub constructor may override it, no luck either.
Instantiate SubClass in RootClass's constructor which just seem stupid.
Basically I want to have 2 classes. The SubClass is the same as RootClass with a few additional fields, which i cant seem to apply a value to.
Depending on a logic I either create a root or sub.
Clearly I'm on the wrong path here, how do I do this?
A base class wouldn't have knowledge of it children classes. What you are saying is either wrong OOP or a very unusual scenario,
How do I make a constructor in RootClass, which can set values to fields found in SubClass
You can't - as far as RootClass is concerned, SubClass doesn't exist.
Also tried setting the constructor in root to virtual, so the sub constructor may override it
You can't - constructors aren't inherited, so there's no concept of "virtual" constructors.
Here's the typical pattern for "chaining" constructors:
public class RootClass
{
public RootClass(int rootProperty)
{
this.RootProperty = rootProperty;
}
public int RootProperty {get; set;}
}
public class SubClass : RootClass
{
v--- call the base constructor
public SubClass(int rootProperty, string subProperty) : base(rootProperty)
{
this.SubProperty = subProperty;
}
public string SubProperty {get; set}
}
Perhaps you're looking for a way for SubClass to call the RootClass constructor?
public class RootClass
{
public RootClass(int foo)
{
}
}
public class SubClass: RootClass
{
public SubClass(int foo)
: base(foo) // calls RootClass constructor
{
// now set Subclass fields
}
}
You cannot access any member of the derived class from the root class.
The typical design pattern is to create a method:
virtual void Init(int a, int b) {}
in your base class, where the parameters are whatever information the derived classes would require to perform self-initialization. Call this from the constructor of the root class.
The derived class would then require a constructor
SubClass() : base() { }
which would guarantee the root class constructor is called, and then its own init method is called.
In this case, however, your best design pattern is to simply subclass.
Suppose the RootClass has member int a and the Subclass int b:
class RootClass {
int a;
RootClass(int a) {
this.a = a;
}
}
class SubClass {
int b;
SubClass(int a, int b) : base(a) {
this.b = b;
}
}
In general, base classes should not have knowledge of their subclasses' implementation details. You should be able to provide your own constructor in the subclass to instantiate its fields, like so:
class SubClass : RootClass
{
private bool subClassfield;
public SubClass() : base()
{
subClassField = true;
}
}
Does that not work as expected? Note the : base() expression, which ensures the SubClass's constructor calls the base class's constructor to guarantee the base class is initialized before proceeding.
A class can not know about the implementation of all the classes that inherit from it.
For reasons out of the scope of the question, I'm needing to dynamically create an instance of a child class that inherits from a base class, calling a constructor that doesn't exist with an argument passed to the base class constructor
Using example below: should create an instance of ExampleClass sending value to argument1 of BaseClass.
class BaseClass
{
public BaseClass()
{
}
public BaseClass(string argument1)
{
//...
}
}
class ExampleClass : BaseClass
{
public ExampleClass()
{
}
}
EDIT: I made another topic where I explain the source or my problem:
Entity Framework DbContext dynamic instatiation with custom Connection String
If I understand it correct you can't modify ExampleClass but need to create an instance of it that uses a different constructor for the base class?
I belive there is not build in way in the framework to achive it, even with reflection.
So your goal should be to bypass the framework and use MSIL
However, this topic I found on SO looks promissing.
Dynamically create type and call constructor of base-class
Do you want to call the base class' constructor?
public ChildClass(string arg1) : base(arg1)
{
//above will invoke base constructor that takes a string argument
}
The only way I can see to do this is to add a ParentClass constructor. I doesn't have to do anything, so I don't see why you can't add it:
public ParentClass(string argument1) : BaseClass(argument1)
{
}
Try this:
class ExampleClass : BaseClass
{
public ExampleClass()
: base(Properties.Settings.Default.MyArgument)
{
}
}
You can use Properties.Settings.Default.MyArgument in order to pass in the value of the argument you want use in the base class constructor without modifying the source code everytime the argument's value needs to be changed (just add it into the projects's Settings, application scoped).
If you can't add a non-default constructor to your ChildClass, then no you can't create an instance of ChildClass calling a base class constructors. Constructors are not inherited. What you need to then is to refactor your base class so that there is way to set the argument not using a constructor. For example see below:
class BaseClass
{
public BaseClass()
{
}
public BaseClass(string argument1)
{
Init(argument1);
}
public void Init(string argument1)
{
//...
}
}
class ExampleClass : BaseClass
{
public ExampleClass()
{
}
}
Then you can create an instance of your ExampleClass and call the Init method to initialize it:
ExampleClass e = (ExampleClass)Activator.CreateInstance.... // or whatever
e.Init(arugment);
I have an asbtract class Example. Another generic class UsesExample uses it as a constraint, with a new() constraint. Later, I create a child to Example class, ExampleChild, and use it with generic class. But somehow when the code in generic class tries to create new copy, it invokes not the constructor in the child class, but the constructor in the parent class. Why does it happen?
Here's the code:
abstract class Example {
public Example() {
throw new NotImplementedException ("You must implement it in the subclass!");
}
}
class ExampleChild : Example {
public ExampleChild() {
// here's the code that I want to be invoken
}
}
class UsesExample<T> where T : Example, new() {
public doStuff() {
new T();
}
}
class MainClass {
public static void Main(string[] args) {
UsesExample<ExampleChild> worker = new UsesExample<ExampleChild>();
worker.doStuff();
}
}
When you crate an object, all constructors are called. At first the base class constructor constructs the object so that the base members are initialized. Later the others constructors in hierarchy are called.
This initialization may call static functions so that it makes sense to call the constructor of an abstract base class event if it has no data members.
Whenever you create a new instance of a derived class, the base class's constructor is called implicitly. In your code,
public ExampleChild() {
// here's the code that I want to be invoked
}
is really turned into:
public ExampleChild() : base() {
// here's the code that I want to be invoked
}
by the compiler.
You can read more on Jon Skeet's detailed blog post on C# constructors.
In a derived class, if a base-class constructor is not called explicitly using the base keyword, then the default constructor, if there is one, is called implicitly.
from msdn
also, you can read here