2011-12-03 5 views
2

私は以下のような一般的なクラスがあります。私の場合はジェネリック型とインスタンスの値だけを持つときに式ツリーを手動で構築する方法はありますか?

public class MyClass<T, TProperty> 
{ 
    MyClass(Expression<Func<T, TProperty>> expression) 
    { 
    } 
} 

は、私が動的にアクティベーターを使用して、そのクラスのインスタンスを作成します。だから私が必要なのは、コンストラクタの式を作成することです。私が持っていることのタイプ(のSystem.Type)とオブジェクト(のSystem.Object)があり、私は以下のような何かをしたい:オブジェクトとして宣言されている

Expression<Func<T, TProperty>> exp = x => someValue; 

「someValueの」が、それは本当のタイプは間違いなくTPropertyあるのです。それは反射によって解決されるので、ここのタイプはオブジェクトです。

問題は、タイプTとTPropertyが汎用であるため、実行時まで型がわからないため、TPropertyに「someValue」をキャストできません。私たちはtypeof(T)、typeof(TProperty)とオブジェクトを持っています。

+2

あなたが呼び出したいものを、コンストラクタやプロパティコードは明らかではありません。これが普通のC#(表現ではない)だった場合、結果はどうなるでしょうか? –

+0

Marcに感謝します。コンストラクタが式を必要とするので、MyClass型のオブジェクトをインスタンス化する必要があるので、記述したように式を動的に作成します。 –

+0

私はいつも使っているトリックです。小さなライブラリを作成し、タイプセーフなバージョンを作成し、コンパイルして、Reflectorで.dllを開きます。ビュー/オプション/最適化で ".NET 2.0"を選択すると、C#コンパイラがあなたのために生成した 'Expression'オブジェクトが表示されます。 – Steven

答えて

4

私は質問を理解していると思います。

サンプル入力を考える:あなたがしたコードと同等を作成したい

Type typeOfT = typeof(int); 
Type typeOfTProperty = typeof(string); 
object someValue = "Test"; 

var myClassInstance = new MyClass<int, string>(t => "Test"); 

は、ここであなたがそれを行うことができます方法です。

まず、表現ツリーを作成します。その後、

var parameter = Expression.Parameter(typeOfT, "t"); 
var body = Expression.Constant(someValue, typeOfTProperty); 

// Will automatically be an Expression<Func<T, TProperty>> without any extra effort. 
var lambda = Expression.Lambda(body, parameter); 

そしてMyClass<T, TProperty>インスタンスを作成するためにリフレクションを使用します。

var myClassType = typeof(MyClass<,>).MakeGenericType(typeOfT, typeOfTProperty); 

// Make the MyClass<,> constructor public first... 
var myClassInstance = Activator.CreateInstance(myClassType, lambda); 
+0

チャームのような作品。ありがとうございました –

関連する問題