C# 使用反射递归地创建实例

C# 使用反射递归地创建实例,c#,recursion,reflection,C#,Recursion,Reflection,} 静态对象CreateForm(string formType、Type controlType、ActivationMode模式) { Form ret=null static void Main(string[] args) { if (args.Length >= 1 && args[0] == "ContainerTest") { string fullname = "xxx.xxx.AddO

} 静态对象CreateForm(string formType、Type controlType、ActivationMode模式) { Form ret=null

    static void Main(string[] args)
    {
        if (args.Length >= 1 && args[0] == "ContainerTest")
        {
            string fullname = "xxx.xxx.AddOptionalComponentDialog";

            //string formType = "PropertySheet";
            string formType = "CustomDialog";
            Type type = null;
            try
            {
                Assembly asm = Assembly.LoadFrom(@"c:\temp\45e2f339-aa63-4525-b722-8e6541873f3b\bin\xxx.dll");
                type = asm.GetType(fullname, true);
            }
            catch (Exception e)
            {
                string msg = e.Message;
            }


            Object ret = CreateForm(formType, type, ActivationMode.CodeExecutionPriorityMixed);
            if (ret is Form)
            {
                Form tForm = (Form)ret;

                Application.Run(tForm);
            }
            else
            {

            }
            return;
        }
公共静态对象CreateInstance(类型,bool genParam) { var constructors=type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)


更新代码时,请尝试以下操作:将递归创建一个包含或不包含无参数构造函数的对象。还应处理私有类型和内部类型

        if (!genParam || constructors.Any(x => !x.GetParameters().Any()))
        {
            return Activator.CreateInstance(type, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { }, null);
        }

        foreach (var constructor in constructors.Where(x => x.GetParameters().Any()))
        {
            return constructor.Invoke(constructor.GetParameters().Select(x => CreateInstance(x.ParameterType, true)).ToArray());
        }

        return null;
    }
.Any是LINQ扩展方法:

构造函数.Any(x=>!x.GetParameters().Any())检查是否存在没有任何参数的构造函数(即无参数构造函数)。如果存在无参数构造函数,则可以使用Activator.CreateInstance创建类型


如果未找到无参数构造函数,则将尝试每个剩余的构造函数以查看是否可以创建该类的实例。此时,将递归调用CreateInstance方法以创建构造函数所需的参数。

我不太清楚您尝试执行的操作是什么?是否要反射式创建实例如果该类具有属性,也将每个属性反射实例化为其类型的实例?我尝试了您的代码,它将失败,因为“没有为该对象定义无参数构造函数”是的,我误解了你想做的。我现在再看一看谢谢你的回答,我的问题是当类型包含一个无参数构造函数和参数构造函数,并且一些参数是内部的或私有的,我的代码无法处理它,我不知道如何递归构造函数。任何和在哪里?我将用e更新答案这些方法的解释我稍微简化了代码并删除了。Whereyes i add system.linq,它返回一个对象,但当使用该对象创建表单{form tForm=(form)instance;Application.Run(tForm);}时,它失败,对象引用未设置为对象的实例。这意味着某些需要的参数没有设置值
        if (!genParam || constructors.Any(x => !x.GetParameters().Any()))
        {
            return Activator.CreateInstance(type, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { }, null);
        }

        foreach (var constructor in constructors.Where(x => x.GetParameters().Any()))
        {
            return constructor.Invoke(constructor.GetParameters().Select(x => CreateInstance(x.ParameterType, true)).ToArray());
        }

        return null;
    }
    public static object CreateInstance(Type type, bool genParam)
    {
        var constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

        if (!genParam || constructors.Any(x => !x.GetParameters().Any()))
        {
            return Activator.CreateInstance(type, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { }, null);
        }

        foreach (var constructor in constructors)
        {
            try
            {
                return constructor.Invoke(constructor.GetParameters().Select(x => CreateInstance(x.ParameterType, true)).ToArray());
            }
            catch{}
        }

        return null;
    }