I started to read about reflection and I wonder, is there a way to create a constructor while the program is running. For example: Get class C and check if C got empty constructor, if not, create on and use it to create this instance. The constructor might have parameters too.
How can I do that? Thank you
In the .NET world, you need to know quite some things.
That means that when you have the following class:
public class Person
{
public int Age
{
get { return 10; }
}
}
It can be instantiated like:
class Program
{
static void Main(string[] args)
{
var person = new Person();
Console.WriteLine(person.Age);
}
}
This would produce the following output:
This means that when you change your person class to the following:
public class Person
{
private Person() { }
public int Age
{
get { return 10; }
}
}
You're not able to instantiate the class using the new() keyword:
var person = new Person();
This would result in a compile error:
That being said, your question is unclear because you would never need to create a constructor at runtime, because of the following:
Now, let's see how to construct classes using reflection using the 3 scenario's above:
You have a class without a constructor.
public class Person
{
public int Age
{
get { return 10; }
}
}
Your instance can be created like:
var instance = (Person)Activator.CreateInstance(typeof(Person));
You have a class with a public constructor
public class Person
{
public Person() { }
public int Age
{
get { return 10; }
}
}
Your instance can be created just in the same way as above, nothing special is needed.
var instance = (Person)Activator.CreateInstance(typeof(Person));
You have a class with a private constructor
public class Person
{
private Person() { }
public int Age
{
get { return 10; }
}
}
Now your instance cannot be created in such an easy way. First, you need to get your ConstructorInfo:
ConstructorInfo c = typeof(Person).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);
With the code above, your requesting information about the constructors which are not public (BindingFlags.NonPublic).
After you have retrieved it, you can construct your object like:
var instance = (Person)c.Invoke(new object[] { });
Let's make it a bit more difficult with the following scenario's:
You have a class with a public constructor that accepts parameters:
public class Person
{
public Person(int age)
{
Age = age;
}
public readonly int Age;
}
The creation is still quite easy:
var instance = (Person)Activator.CreateInstance(typeof(Person), 15);
You just need to pass all your parameters in the same way as they are defined in your constructor.
You have a class with a private constructor that accepts parameters:
public class Person
{
public Person(int age)
{
Age = age;
}
public readonly int Age;
}
Again, we'll need the ConstructorInfo object, but now we need to specify with types of parameters are constructor is accepting. In the example above, this is an integer:
ConstructorInfo c = typeof(Person).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(int) }, null);
Now, you can create an object and as a last parameter you specify all the arguments to construct your object.
var instance = (Person)c.Invoke(new object[] { 15 });
So, this was a very long post about reflection but I hope that I mde some things clear. At least, it should be clear right now why you don't need to add a constructor at runtime in able to invoke an object.
You could create a new Type
via Reflection.Emit
but creating a constructor for existing type is not possible as constructors should be there in metadata of the type in the assembly. You need to declare the constructor upfront.
If you use Mono.Cecil
you could add new constructor to a type, then save it in a new assembly(but that's different story).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With