Assume a class with a parameterized constructor as:
MyObject(string param1, string param2, string param2)
{
...
}
I have a Generic
method that returns an instance of the Generic Class
and
MyObject
is one of such instances.
How can I instantiate a generic class with a parameterized constructor and pass null values to all its parameters? This is needed as properties of the generic class get populated at a slightly later stage.
I have tried using Activator
as:
public static T GetGenericObject<T>()
{
T resource = (T)Activator.CreateInstance(typeof(T), null);
...
}
But I get exception that I got no parameterless constructor in MyObject
. I know I could add one easily but the class cannot be modified (don't ask why).
Constructing an Instance of a Generic Type A generic type is like a template. You cannot create instances of it unless you specify real types for its generic type parameters. To do this at run time, using reflection, requires the MakeGenericType method.
The Activator. CreateInstance method creates an instance of a type defined in an assembly by invoking the constructor that best matches the specified arguments. If no arguments are specified then the constructor that takes no parameters, that is, the default constructor, is invoked.
You could detect how many parameters there are via reflection, and then pass in null values for each of them in Activator.CreateInstance()
:
var parameters = typeof(T)
.GetConstructors()
.Single()
.GetParameters()
.Select(p => (object)null)
.ToArray();
T resource = (T)Activator.CreateInstance(typeof(T), parameters);
Note that this assumes there's only one constructor, and it'll only work for reference types, so it's fairly fragile.
Use the overload that takes parameters and create an object array to pass where null represents each needed parameter.
In light of your comment, you can certainly tell the method to create an initialized but empty object array based on a fixed number of elements. However, as mentioned in other comments, this is extremely dangerous and will cause you headaches down the road.
var instance = GetGenericObject<MyObject>(3);
public static T GetGenericObject<T>(int numberOfNullParametersToPass)
{
var nullParams = new object[numberOfNullParametersToPass];
T resource = (T)Activator.CreateInstance(typeof(T), nullParams);
return resource;
}
As your code currently stands, you are explicitly telling Activator.CreateInstance
to choose the parameterless constructor. By specifying all three arguments (even though they are null), you are selecting the correct constructor.
At some point in the call chain you need to tell Activator.CreateInstance
which constructor to choose. An alternative is to choose the first possible constructor.
public static T GetGenericObject<T>()
{
var paramLength = typeof(T).GetConstructors().FirstOrDefault().GetParameters().Length;
var parameters = new object[paramLength];
T resource = (T)Activator.CreateInstance(typeof(T), parameters);
return resource;
}
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