Instantiate a parameterized shared object with all parameters set to null
Let's assume a class with a parameterized constructor like:
MyObject(string param1, string param2, string param2)
{
...
}
I have a method Generic
that returns an instance Generic Class
and
MyObject
is one of those instances.
How can I instantiate a generic class with a parameterized constructor and pass null values to all of its parameters? This is necessary as the properties of the generic class are populated a little later in the stage.
I tried to use Activator
like:
public static T GetGenericObject<T>()
{
T resource = (T)Activator.CreateInstance(typeof(T), null);
...
}
But I am getting an exception that I have no parameterless constructor in MyObject
. I know I can add one easily, but the class cannot be changed (don't ask why).
source to share
You can determine how many parameters there are through reflection, and then pass NULL values for each one to 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 is only one constructor and it will only work for reference types, so it is rather fragile.
source to share
Use an overload that takes parameters and creates an array of objects to pass, where null represents each required parameter.
In light of your comment, you can of course say that the method creates an initialized but empty array of objects based on a fixed number of elements. However, as mentioned in other comments, this is extremely dangerous and will give you headaches.
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;
}
Since your code is currently standing, you are explicitly saying Activator.CreateInstance
to choose a parameterless constructor. By specifying all three arguments (even if they are zero), you choose the correct constructor.
At some point in the call chain, you need to tell Activator.CreateInstance
which constructor to choose. The 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;
}
source to share