如何在不知道所有参数的情况下动态调用对象的构造函数

本文关键字:情况下 动态 对象 构造函数 调用 参数 不知道 | 更新日期: 2023-09-27 18:06:39

到目前为止,我已经完成了以下内容:

var constructor = typeof (ParentModel).GetConstructor(FieldInformationTypes);
var model = (ParentModel)constructor.Invoke(Values.Values.ToArray());
return model;

和FieldInformationTypes(在具有上述代码的类的超类中)

protected Type[] FieldInfoTypes;
public Type[] FieldInformationTypes
{
    get
    {
        if (FieldInfoTypes == null) return FieldInfoTypes;
        var memberTypes = (
            from fieldInfo in FieldInformation
            select fieldInfo.MemberType).ToArray();
        FieldInfoTypes = (
            from memberType in memberTypes
            select memberType.GetType()).ToArray();
        return FieldInfoTypes;
    }
}
protected FieldInfo[] FieldInfos;
public FieldInfo[] FieldInformation
{
    get
    {
        // don't GetFields all the time
        if (FieldInfos != null) return FieldInfos;
        FieldInfos = typeof(T).GetFields(
            BindingFlags.Public |
            BindingFlags.NonPublic |
            BindingFlags.Instance);
        return FieldInfos;
    }
}

其中T是我试图动态创建的构造函数的类。

Values只是stringsobjects的字典,其中字符串是参数字段名,值可以是任意值。

我知道有了命名参数,ParentModel可以这样创建:

new ParentModel(
    children: _children,
    isResponsible: _isResponsible);

或者通过这种方法:

new ParentModel()
{
    Children = _children,
    IsResponsible = _isResponsible
};

调用方法(在我的例子中是构造函数)的这两种技术看起来都非常像散列/字典。因此,我觉得应该可以通过字典动态调用方法。我的问题是:怎么做?

理想情况下,我希望能够通过这样做来调用一个方法:

new MyObject(myDictionaryOfParameters.ToNamedParameter());

或者类似的东西。

如何在不知道所有参数的情况下动态调用对象的构造函数

GetConstructor()返回的ConstructorInfo的扩展方法如何:

    public static object Invoke(this ConstructorInfo constructor, Dictionary<string, object> parameters)
    {
        List<object> parameterValues = new List<object>();
        foreach(var parameterInfo in constructor.GetParameters())
        {
            if (parameters.ContainsKey(parameterInfo.Name))
                parameterValues.Add(parameters[parameterInfo.Name]);
            else
                parameterValues.Add(null);
        }
        return constructor.Invoke(parameterValues.ToArray());
    }

,那么你可以这样调用:

var constructor = typeof (ParentModel).GetConstructor(FieldInformationTypes);
var model = (ParentModel)constructor.Invoke(Values);
return model;

假设在您的第一个示例中Values是您的Dictionary<string, object>,您所拥有的将不起作用。Dictionaries不保持顺序,因此您不能确保从字典中获得的值与构造函数中的参数匹配。您可以使用GetParameters方法来排列您的参数:

var constructor = typeof (ParentModel).GetConstructor(FieldInformationTypes);
var parameters = constructor.GetParameters();
var model = (ParentModel)constructor.Invoke(parameters.Select(p => Values[p.Name]).ToArray());
return model;

使用命名形参不会将形参作为字典传递。编译器将把该调用重写为普通的方法调用。同样,第二个例子没有向构造函数传递任何参数。

new ParentModel()
{
    Children = _children,
    IsResponsible = _isResponsible
};

调用默认构造函数并设置ChildrenIsResponsible属性。这只是语法糖:

var model new ParentModel();
model.Children = _children;
model.IsResponsible = _isResponsible;
相关文章: