2009-03-17 6 views
5

私はLINQ-to-XMLを使用してファイルにオブジェクトのリストを照会しています。それらはすべて同じ構造(設定された数のオプション、不確定な長さのパラメータのリスト)を持ちます。 XMLファイルの名前に基づいて、私は全く異なるものにパラメータを使用したいので、このオブジェクトのサブクラスを作成しました。C#でどのように動的にコンストラクタを呼び出すことができますか?

私の質問は - ケースステートメントのようなことをせずに、正しいコンストラクタを動的に呼び出すにはどうすればいいですか?あるいは、XMLとは異なるサブクラスをエレガントにインスタンス化するソリューションは他の場所にありますか?

class Object1 
{ 
    string name; 
    OptionObj opt; 
    List<Param> parameters; 
} 

class sonOfObject : Object1 
{ 
    public void ExecuteSomething() 
    { 
     //do something with the parameters 
    } 
} 

class secondSonOfObject : Object1 
{ 
    public void ExecuteSomething() 
    { 
     //do something entirely different with the parameters 
    } 
} 

var query = from x in xmlDoc.Descendants("Object") 
    select new Object 
    { 
     //select the object from the XML 
    } 

は、このコードのビットの後、私はより一般的なクエリオブジェクトからsonOfObjectを作るためにコピーコンストラクタを使用することができます。しかし、子クラスの名前に基づいてどのように動的に行うのですか?

私はあなたがタイプからMETHODINFOを取得し、ALA、それを呼び出すことができることを知っている...

MethodInfo m = t.GetMethod(someName); 
m.Invoke(yourObj, null); 

しかし、それは私が9またはこれらの子クラスのオブジェクトの10のインスタンスを作成しなければならない意味(とタイプになるだろうそれらのそれぞれについて)、そして何らかの種類の事件声明でなお終わる。

子クラスのコンストラクタを動的に呼び出すより洗練された方法がありますか?

答えて

3

クラスがこのスキームに参加するためには、カスタム属性でマークして、「XML名」を付けます。

次に、反射を使用して、その属性でマークされたTypeをすべて見つけ、Dictionary<string, Type>に入れます。この時点で、システムにタイプを与える可能性がある他のアセンブリをどのように見つけるかを決定する必要があります。簡単な方法は、同じディレクトリ内の.DLLという拡張子を持つ他のファイルを探すことです。

次に、あなただけの名前でDictionaryTypeを検索し、Type.GetConstructorConstructorInfo.Invokeを呼び出し、対応するTypeのインスタンスを作成するために使用するXMLから文字列を持っている時はいつでも。

この利点は、XMLの識別子がコードの物理レイアウトから分離されていることです。アセンブリ内で型を移動したり、古いXMLファイルを無効にしたりせずに名前を変更できます。

+0

+1私はOPを再読した後、これは本当に良い解決策であると信じています。 –

7

Activator.CreateInstanceあなたは文字列としてクラス名を渡すことができ、それはあなたにそのクラスの新しいインスタンスを返します。

関連する問題