反射 - 使用参数调用构造函数

Sim*_*mon 10 c# reflection enums

我从加载的程序集中读取类型,例如:

var someType = loadedAssemblies
            .Where(a => a != null && a.FullName.StartsWith("MY."))
            .SelectMany(a => a.GetTypes())
            .Distinct()
            .ToArray()[0];
Run Code Online (Sandbox Code Playgroud)

如果counstructor有参数,我可以读它们:

ParameterInfo[] parameters = classType.GetConstructors()[0].GetParameters();
Run Code Online (Sandbox Code Playgroud)

我想用默认参数值调用构造函数,或者如果参数是枚举,则使用第一个枚举值.如果只有一个参数并且它是枚举,则它的工作方式如下:

object curObject = Activator.CreateInstance(classType, new object[] { parameters[0].ParameterType.GetEnumValues().GetValue(0) });
Run Code Online (Sandbox Code Playgroud)

如果有更多参数,我该怎么做?我需要创建对象来读取属性:

var propertyInfo = someType.GetProperty("EntityType");
string entityType = propertyInfo.GetValue(curObject, null).ToString();
Run Code Online (Sandbox Code Playgroud)

Fab*_*jan 7

好吧,你可以创建自己的Factory和write方法,用它们的默认参数检查类型的构造函数:

public static class MyFactory
{
    public static T MyCreateInstance<T>()
        where T : class
    {
        return (T) MyCreateInstance(typeof (T));
    }

    public static object MyCreateInstance(Type type)
    {
        var ctor = type
            .GetConstructors()
            .FirstOrDefault(c => c.GetParameters().Length > 0);

        return ctor != null
            ? ctor.Invoke
                (ctor.GetParameters()
                    .Select(p =>
                        p.HasDefaultValue? p.DefaultValue :
                        p.ParameterType.IsValueType && Nullable.GetUnderlyingType(p.ParameterType) == null
                            ? Activator.CreateInstance(p.ParameterType)
                            : null
                    ).ToArray()
                )
            : Activator.CreateInstance(type);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用这个方法:

var classType = loadedAssemblies
            .Where(a => a != null && a.FullName.StartsWith("MY."))
            .SelectMany(a => a.GetTypes())
            .Distinct()
            .ToArray()[0];

var curObject = MyFactory.MyCreateInstance(classType);

// This will return an array of values

object[] values = classType
                 .GetFields()
                 .Select(f => f.GetValue(curObject))
                 .ToArray();
Run Code Online (Sandbox Code Playgroud)

PS这是一个DotNet小提琴示例.

更新:

根据您使用的方案更改代码.现在我们有两个方法,一个返回对象,另一个可以将它转换为类型T.

我也更新了DotnetFiddle,请检查一下.