创建参数化通用对象的实例,并将所有参数设置为null

时间:2015-07-10 19:09:12

标签: c# generics constructor instantiation activator

假设一个带有参数化构造函数的类为:

MyObject(string param1, string param2, string param2)
{
   ...
}

我有一个Generic方法,它返回Generic ClassMyObject的实例 Activator就是其中之一。

  

如何使用参数化构造函数实例化泛型类   并将null值传递给它的所有参数?这是必要的   通用类的属性稍后会填充   阶段。

我尝试使用public static T GetGenericObject<T>() { T resource = (T)Activator.CreateInstance(typeof(T), null); ... } 作为:

MyObject

但我得到的异常是toSource()中没有无参数构造函数。我知道我可以轻松添加一个但是类不能修改(不要问为什么)。

3 个答案:

答案 0 :(得分:5)

您可以通过反射检测出有多少参数,然后在Activator.CreateInstance()中为每个参数传递空值:

var parameters = typeof(T)
    .GetConstructors()
    .Single()
    .GetParameters()
    .Select(p => (object)null)
    .ToArray();
T resource = (T)Activator.CreateInstance(typeof(T), parameters); 

请注意,这假设只有一个构造函数,并且它只适用于引用类型,因此它非常脆弱。

答案 1 :(得分:3)

使用带参数的重载并创建一个对象数组来传递,其中null表示每个需要的参数。

根据您的评论,您当然可以告诉该方法基于固定数量的元素创建初始化但空的对象数组。但是,正如其他评论中所提到的,这是非常危险的,并且会让你头疼。

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

正如您的代码目前所示,您明确告诉Activator.CreateInstance选择无参数构造函数。通过指定所有三个参数(即使它们为null),您正在选择正确的构造函数。

在调用链的某个时刻,您需要告诉Activator.CreateInstance选择哪个构造函数。另一种方法是选择第一个可能的构造函数。

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 :(得分:0)

下面是简单的方法,不用担心参数,避免错误没有默认的construtor存在

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