2012-01-26 3 views
-1

この関数は、アセンブリを読み込んで、ユーザーがリストからフォームを選択させてから呼び出しようとします。成功した場合は、フォームを返します。事前に知られていないコンストラクタにパラメータを供給するにはどうすればよいですか?

私の問題は、予想される型のパラメータでコンストラクタをインスタンス化する方法です。コンストラクタがList<string>の空の場合はnull 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; 
} 
+0

何それは 'IList'を想定している場合? – dasblinkenlight

+0

あなたは何を達成しようとしていますか?コンストラクタが空でなければならないリストを必要とすると仮定します。あるいは、すべての要素がプリミティブ、空ではなくヌルでないコレクション、または順番にそのようなコンストラクタを持つオブジェクトのインスタンスのみを取ることは知っていますか?その場合は、ユーザが値を選択できるように –

+0

boiutが機能する可能性があります。使用する_sensible_値を調べる方法はありません。例えば。空のリストが無効になる可能性があります –

答えて

0

tからオブジェクトを作成するにはこのメソッドは非常にうまく動作します。

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を使用すると、文字列リストはnullになります。これはコンストラクタの有効なパラメータではありません。 – Stig

+0

@Stig Hm ...私はあなたに何をすべきかを書いた。問題は、どのようなパラメータタイプが必要か、動的かどうかを知っていますか、どのタイプのパラメータがわからないのですか?動的:オブジェクトp1 = Activator.CreateInstance(typeof(parameters [i]))、Activate.CreateInstance(t、[p1])をFormとして返します。 –

+0

解決策に近づきましたが、インターフェイスでは機能しません。 – Stig

関連する問題