createinstance递归使用Reflection

时间:2015-03-08 22:06:25

标签: c# recursion reflection

    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;
        }

} static Object CreateForm(string formType,Type controlType,ActivationMode mode)         {             表格ret = null;

    retry:
        switch (formType)
        {
            case "PropertySheet":

            case "CustomDialog":
                ret = (Form)InstanceCreator.CreateInstance(controlType, true);
                if (ret != null)
                {
                    ret.AccessibleName = controlType.FullName;
                }
                break;

            default:
                {
                    if (controlType.IsSubclassOf(typeof(SmsPageControl)))
                    {
                        formType = "PropertySheet";
                        goto retry;
                    }
                    if (controlType.IsSubclassOf(typeof(Form)))
                    {
                        formType = "CustomDialog";
                        goto retry;
                    }
                    if (controlType.IsSubclassOf(typeof(SmsWizardPage)))
                        //||                            controlType.IsSubclassOf(typeof(SmsPropertyPage)))
                    {
                        throw new Exception("There is no need to check this control");
                    }
                    UserControl control = (UserControl)CreateInstanceOfType(controlType, mode);
                    UserControlHolder holder = new UserControlHolder();
                    holder.HostUserControl(control);
                    ret = holder;
                }
                break;
        }
        return ret;
    }

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.Where(x => x.GetParameters().Any()))
        {
            return constructor.Invoke(constructor.GetParameters().Select(x => CreateInstance(x.ParameterType, true)).ToArray());
        }

        return null;
    }

1 个答案:

答案 0 :(得分:1)

更新代码,试试这个:将以递归方式创建一个带或不带无参数构造函数的对象。还应该处理私人和内部类型。

    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;
    }

.Any是LINQ扩展方法:.Any()

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

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