C# 如何向施工人员提供事先未知的参数?

C# 如何向施工人员提供事先未知的参数?,c#,createinstance,C#,Createinstance,此函数将加载一个程序集,让用户从列表中选择一个表单,然后尝试调用它。如果成功,请返回表单 我的问题是如何用预期类型的参数实例化构造函数。 如果构造函数期望List则应提供空的List,而不仅仅是null 有什么想法吗 private Form SelectForm(string fileName) { Assembly assembly = Assembly.LoadFrom(fileName); var asmTypes = assembly.GetTypes().Where(

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

我的问题是如何用预期类型的参数实例化构造函数。 如果构造函数期望
List
则应提供空的
List
,而不仅仅是null

有什么想法吗

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;
}
private Form SelectForm(字符串文件名)
{
Assembly=Assembly.LoadFrom(文件名);
var asmTypes=assembly.GetTypes(),其中(F=>F.IsSubclassOf(typeof(Form));
字符串SelectedFormName;
使用(FrmSelectForm=新FrmSelectForm())
{
form.DataSource=(来自asmTypes中的行)
选择新的{row.Name,row.Namespace,row.BaseType}).ToList();
if(form.ShowDialog(this)!=DialogResult.OK)
返回null;
SelectedFormName=form.SelectedForm;
}
类型t=asmTypes.Single(F=>F.Name==SelectedFormName);
foreach(t.GetConstructors()中的变量ctor)
{
尝试
{
object[]parameters=新对象[ctor.GetParameters().Length];
对于(int i=0;i
如果您知道什么是参数类型,请替换:

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


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

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

如果它需要一个
IList
,该怎么办?您想要实现什么?假设构造函数需要一个必须为非空的列表,您应该向列表中添加什么使其工作?或者,您知道所有的构造函数都只接受原语、可以为空但不能为null的集合,或者对象的实例,而对象的实例又有这样的构造函数吗?在这种情况下,让用户选择值可能会起作用——无法确定使用哪些合理的值。空列表可能是invliadI,我希望有一种通用的方法来生成对构造函数有效的变量。如果构造函数对提供的参数进行了验证,并且不接受空数据。这超出了提供参数的一般方式。i、 e.然后您需要知道构造函数想要/需要什么,这正是我所要求的,以及如何创建这些参数。当我使用DafaultValue时,字符串列表将变为null,这不是构造函数的有效参数。@Stig Hm…我写了你应该做的事情。问题是:您是否知道参数类型应该是什么,或者它可以是动态的,而您不知道参数类型是什么?对于dynamic:objectp1=Activator.CreateInstance(typeof(parameters[i])),则:以表单形式返回Activator.CreateInstance(t[p1]);如果您有一个接口,我认为这可能是一个问题,因为您不知道要创建实现该接口的类型。。。
object p1 = Activator.CreateInstance(parameters[i].ParameterType), 
return Activator.CreateInstance(t, [p1]) as Form;
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;
    }
}