-1

该函数将加载一个程序集,让用户从列表中选择一个表单,然后尝试调用它。如果成功,则返回表单。

我的问题是如何使用预期类型的​​参数实例化构造函数。如果构造函数期望应该提供List<string>一个空值,而不仅仅是空值。List<String>

有任何想法吗?

private Form SelectForm(string fileName)
{
    Assembly assembly = Assembly.LoadFrom(fileName);
    var asmTypes = assembly.GetTypes().Where(F => F.IsSubclassOf(typeof(Form)));
    string SelectedFormName;
    using (FrmSelectForm form = new FrmSelectForm())
    {
        form.DataSource = (from row in asmTypes
                           select new { row.Name, row.Namespace, row.BaseType }).ToList();

        if (form.ShowDialog(this) != DialogResult.OK)
            return null;
        SelectedFormName = form.SelectedForm;
    }

    Type t = asmTypes.Single<Type>(F => F.Name == SelectedFormName);
    foreach (var ctor in t.GetConstructors())
    {
        try
        {
            object[] parameters = new object[ctor.GetParameters().Length];
            for (int i = 0; i < ctor.GetParameters().Length; i++)
            {
                parameters[i] = ctor.GetParameters()[i].DefaultValue;
            }
            return Activator.CreateInstance(t, parameters) as Form;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    return null;
}
4

2 回答 2

1

如果您知道什么是参数类型,请替换:

parameters[i] = ctor.GetParameters()[i].DefaultValue;

parameters[i] = new List<string>();

如果您不知道,则需要使用相同的反射方法创建实例:

object p1 = Activator.CreateInstance(parameters[i].ParameterType), 
return Activator.CreateInstance(t, [p1]) as Form;
于 2012-01-26T13:32:00.777 回答
0

为了从类型定义创建对象,此方法非常有效。

private Form SelectForm(string fileName,string formName)
{
    Assembly assembly = Assembly.LoadFrom(fileName);
    var asmTypes = assembly.GetTypes().Where(F => F.IsSubclassOf(typeof(Form)));

    Type t = asmTypes.Single<Type>(F => F.Name == formName);
    try
    {
        var ctor = t.GetConstructors()[0];
        List<object> parameters = new List<object>();
        foreach (var param in ctor.GetParameters())
        {
            parameters.Add(GetNewObject(param.ParameterType));
        }
        return ctor.Invoke(parameters.ToArray()) as Form;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    return null;
}

...

public static object GetNewObject(Type t)
{
    try
    {
        return t.GetConstructor(new Type[] { }).Invoke(new object[] { });
    }
    catch
    {
        return null;
    }
}
于 2012-01-30T12:01:07.127 回答