如何在不知道所有参数的情况下动态调用对象的构造函数
本文关键字:情况下 动态 对象 构造函数 调用 参数 不知道 | 更新日期: 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
只是strings
到objects
的字典,其中字符串是参数字段名,值可以是任意值。
我知道有了命名参数,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
};
调用默认构造函数并设置Children
和IsResponsible
属性。这只是语法糖:
var model new ParentModel();
model.Children = _children;
model.IsResponsible = _isResponsible;