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;
}
答案 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方法以创建构造函数所需的参数。