2012-01-26 54 views
-1

該函數將加載一個程序集,讓用戶從列表中選擇一個表單,然後嘗試調用它。如果成功,則返回表單。如何向構造函數提供參數,事先不知道?

我的問題是如何實例化具有預期類型的​​參數的構造函數。 如果構造函數期望List<string>應該提供一個空的List<String>,而不僅僅是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; 
} 
+0

如果它所希望的'IList'? – dasblinkenlight

+0

你想達到什麼目的?假設構造函數需要一個非空的列表,你應該添加到列表中以使其工作嗎?或者你是否知道所有的ctors只有基元,可以爲空但不爲空的集合,或者具有這種構造器的對象實例?在這種情況下,它可能會運行 –

+0

boiut讓用戶選擇值 - 沒有辦法計算出什麼_sensible_值使用。例如。一個空列表可能會被調用 –

回答

0

爲了創建從t ypes定義這個方法工作得很好。

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

恩,那正是我所要求的,如何創建這些參數。當我使用DafaultValue時,一個字符串列表將變爲空,這對構造函數來說不是一個有效的參數。 – Stig

+0

@Stig Hm ...我給你寫了你應該做的事情。問題是:你知道什麼樣的參數類型,或者它可以是動態的,你不知道什麼類型的參數是?對於dynamic:object p1 = Activator.CreateInstance(typeof(parameters [i])),則:返回Activator.CreateInstance(t,[p1])作爲Form; –

+0

現在你更接近解決方案,但它不適用於接口... – Stig

相關問題