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

Create instance of a parameterized generic object with all parameters set to null

假设 class 的参数化构造函数为:

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

我有一个 Generic 方法 returns Generic Class 的一个实例和 MyObject 就是其中之一。

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.

我试过使用 Activator 作为:

public static T GetGenericObject<T>()
{
   T resource = (T)Activator.CreateInstance(typeof(T), null); 
   ... 
}

但我得到异常,我在 MyObject 中没有无参数构造函数。我知道我可以很容易地添加一个,但是无法修改 class(不要问为什么)。

使用带参数的重载并创建一个对象数组来传递,其中 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 选择无参数构造函数。通过指定所有三个参数(即使它们为空),您正在选择正确的构造函数。

在调用链中的某个点,您需要告诉 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;
}

你可以通过反射检测出有多少个参数,然后在Activator.CreateInstance():

中为每个参数传入空值
var parameters = typeof(T)
    .GetConstructors()
    .Single()
    .GetParameters()
    .Select(p => (object)null)
    .ToArray();
T resource = (T)Activator.CreateInstance(typeof(T), parameters); 

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

下面是不用担心参数的简单方法,避免默认构造函数不存在的错误

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