通过匿名类型的反射实例化对象

本文关键字:反射 实例化 对象 类型 | 更新日期: 2023-09-27 18:13:49

我使用以下方法通过反射实例化对象

 Activator.CreateInstance(Type type, params object[] parameters)

其中"parameters"是运行时传递给构造函数的参数列表。

然而,我希望这个过程对团队中的其他开发人员更直观,而不是传递object[]参数数组,我希望他们传递一个匿名对象,例如

 // note, invalid code
 Activator.CreateInstance(typeof(MyType), new { paramName1 = "abc", paramName2 = "xyz})

由于框架方法不支持它,有没有人有代码的例子,将一个匿名对象转换成一个数组?请注意,参数的顺序对Activator.CreateInstance()方法很重要,因为这是它进行参数匹配的方式。显然,这很容易出错,这就是为什么我更喜欢使用匿名类型。

欢迎提出任何建议。

亚历克。

通过匿名类型的反射实例化对象

我不会使用Activator.CreateInstance。我将使用Type.GetConstructors()来获取所有构造函数,然后找到一个具有与匿名类型具有属性相同数量的参数并且具有相同名称的构造函数。如果可能有多个不同类型的构造函数,则需要添加额外的逻辑来检查每个参数类型是否与相关的属性类型兼容。

类似:

public object CreateInstance(Type type, Object parameterMapping)
{
    var ctors = type.GetConstructors();
    var properties = parameterMapping.GetType().GetProperties();
    foreach (var ctor in ctors)
    {
        var parameters = ctor.GetParameters();
        if (parameters.Length != properties.Length)
        {
            continue;
        }
        object[] args = new object[parameters.Length];
        bool success = true;
        for (int i = 0; i < parameters.Length; 
        {
            var property = parameterMapping.GetType().GetProperty(parameter.Name);
            if (property == null)
            {
                success = false;
                break;
            }
            // TODO: Check property type is appropriate too
            args[i] = property.GetValue(parameterMapping, null);
        }
        if (!success)
        {
            continue;
        }
        return ctor.Invoke(args);
    }
    throw new ArgumentException("No suitable constructor found");
}