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);
Related
I am currently working on a ASP.NET Core MVC application (I am migrating a project from .NET to .NET Core) and I was wondering about the base constructors.
Specifically, codes like:
public partial class CompanyFormsContext : DbContext
{
public CompanyFormsContext()
: base("name=CompanyFormsContext")
{
}
public CompanyFormsContext(string connName)
: base("name=" + connName)
{
}
...
}
This was a ASP.NET syntax and now DbContext does not accept string as a parameter, but rather accepts DbContextOptionsBuilder.
What my question is: How and when are the base class constructors are useful? Here I can have an empty constructor for CompanyFormsContext but I can still pass a parameter for the base class constructor?
I am guessing that base constructor is related to DbContext since CompanyFormsContext is a child class. However, I am confused as to why I may want to use the base class here.
Here are the two ways that we call these methods in the project:
//First
var db = new CompanyFormsContext(siteUrl.StartsWith("http://www.") ? "CompanyFormsContext" : "CompanyFormsContextQA");
//Second
var env = Request.Headers["environment"].First();
var db = new CompanyFormsContext(env);
and I would probably have to modify these in a way that they would work with the new .NET Core syntax. Which constructor would be called for each of these instances?
Shortly, I want to learn about how in this context base classes are used and what is their general purpose. Thanks
A base class constructor is used if there's some kind of initialization that's used in many different scenarios. For example, if you had something like
public bool Abc { get; set; }
private readonly string x;
private readonly string newName;
public Test(string x, string newName)
{
Abc = true;
thix.x = x;
this.newName = newName;
}
(yeah, pretty dumb example, but anyway) and you always wanted that initialization to happen you probably don't want to have to type that over and over again every time you have a new derived class. Not only would that be annoying, it would be bad from a maintenance perspective; if you had to change the logic for some reason you'd have to go to every single place where you had typed it and change it, and if you accidentally missed one you'd introduce a bug into your system.
Note that it's possible for both the parent type and the derived type to have several constructors. For example:
public abstract class SomeClass
{
public SomeClass(string a, string b)
{
// ...
}
public SomeClass()
{
//...
}
}
public SomeDerivedType : SomeClass
{
public SomeDerivedType(string a, string b) : base(a, b)
{
// ...
}
public SomeDerivedType() : base("test", "string")
{
// ..
}
}
It's perfectly valid for the base constructor and derived type constructor to have different parameters. If you think about it, that makes sense; you're calling a completely different constructor. It would, for example, be perfectly valid to do the following:
public SomeDerivedType()...
{
// The CollectionType constructor has a different number of parameters than SomeDerivedType does
abc = new CollectionType<int>(1, 2, 3, 4, 5);
}
Take at MSDN look at https://msdn.microsoft.com/en-us/library/ms173115.aspx
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:
...
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.
A constructor can invoke another constructor in the same object by using the this keyword. Like base, this can be used with or without parameters, and any parameters in the constructor are available as parameters to this, or as part of an expression. For example, the second constructor in the previous example can be rewritten using this:
You call your constructor with string argument. So the one that accepts a string is executed. The constructor of your base class is also executed due to : base ().
You typically use a base constructor if you want to execute the code inside that constructor.. and you can't or don't want to copy that code to your childconstructor. Which is always unless you don't want the base constructor code to be executed. You kind of override it by not using base ()
From https://msdn.microsoft.com/en-us/library/hfw7t1ce.aspx:
public class BaseClass
{
int num;
public BaseClass()
{
Console.WriteLine("in BaseClass()");
}
public BaseClass(int i)
{
num = i;
Console.WriteLine("in BaseClass(int i)");
}
public int GetNum()
{
return num;
}
}
public class DerivedClass : BaseClass
{
// This constructor will call BaseClass.BaseClass()
public DerivedClass() : base()
{
}
// This constructor will call BaseClass.BaseClass(int i)
public DerivedClass(int i) : base(i)
{
}
static void Main()
{
DerivedClass md = new DerivedClass();
DerivedClass md1 = new DerivedClass(1);
}
}
/*
Output:
in BaseClass()
in BaseClass(int i)
*/
Here I realized that given no information in the DerivedClass, BaseClass constructor is called. Therefore, for my question:
public partial class CompanyFormsContext : DbContext
{
public CompanyFormsContext()
: base("name=CompanyFormsContext")
{
}
public CompanyFormsContext(string connName)
: base("name=" + connName)
{
}
...
}
DbContext(string) is called in both cases but in one case the input parameter is "name=CompanyFormsContext" and in the other one it is "name=" + connName.
Therefore, to be able to change into a DbContextOptionsBuilder parameter with the .NET Core syntax, I could define two instances of OptionsBuilders and then call them in the base constructor according to the input of the CompanyFormsContext.
I believe this is what I was looking for and I was able to get to this thanks to other answers. I will improve my answer and share the full code once I complete it.
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() {}
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 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
I need to instatiate a C# type dynamically, using reflection. Here is my scenario: I am writing a base class, which will need to instantiate a certain object as a part of its initialization. The base class won't know what type of object it is supposed to instantiate, but the derived class will. So, I want to have the derived class pass the type to the base class in a base() call. The code looks something like this:
public abstract class MyBaseClass
{
protected MyBaseClass(Type myType)
{
// Instantiate object of type passed in
/* This is the part I'm trying to figure out */
}
}
public class MyDerivedClass : MyBaseClass
{
public MyDerivedClass() : base(typeof(Whatever))
{
}
}
In other words, the base class is delegating to its derived type the choice of the object type to be instantiated.
Can someone please assist?
Try Activator.CreateInstance(Type)
http://msdn.microsoft.com/en-us/library/wccyzw83.aspx
You're looking for Activator.CreateInstance
object instance = Activator.CreateInstance(myType);
There are are various overloads of this method that can take constructor arguments or other information to find the type (such as names in string form)
http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx
You might want to use generics instead:
public abstract class MyBaseClass<T> where T : new()
{
protected MyBaseClass()
{
T myObj = new T();
// Instantiate object of type passed in
/* This is the part I'm trying to figure out */
}
}
public class MyDerivedClass : MyBaseClass<Whatever>
{
public MyDerivedClass()
{
}
}
The where T : new() is required to support the new T() construct.