문제

This function will load an assembly, let the user select a form from a list, and then try to invoke it. If successful, returning the form.

My problem is how to instantiate the constructor with parameters that is of the expected type. if the constructor expect List<string> an empty List<String> should be supplied, not just null.

Any Ideas?

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;
}
도움이 되었습니까?

해결책 2

in order to create objects from types definitions this method works very well.

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

다른 팁

If you know what is a parameter type, replace:

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

to

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

If you don't know, you need create instance using same reflection methods:

object p1 = Activator.CreateInstance(parameters[i].ParameterType), 
return Activator.CreateInstance(t, [p1]) as Form;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top