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

时间:2014-07-20 15:13:33

标签: c# .net reflection

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

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

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

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

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

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

欢迎任何建议。

艾力。

1 个答案:

答案 0 :(得分:4)

我不会使用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");
}