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

Ale*_*yte 1 .net c# reflection

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

 Activator.CreateInstance(Type type, params object[] parameters)
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

任何建议都将不胜感激。

亚历克

Jon*_*eet 5

我不会用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");
}
Run Code Online (Sandbox Code Playgroud)