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).

+3


source to share


3 answers


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.

+5


source


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;
}

      

+2


source


Below is a simple method without worrying about the parameter and avoiding the default missing error.

var ctors = typeof(T).GetConstructors();
var ctor = ctors[0];
var instance = ctor.Invoke(new object[ctor.GetParameters().Length]);

      

0


source







All Articles