2011-10-26 10 views
0

私は実行時にしか知りませんタイプのラムダ式(ユーザ入力に基づいていますが、現時点では概念の証明にダミー値を使用しています)を動的に作成しています。したがって、私は実行時(TResultは常にbool)になるまで型を知らないので、Func<T,TResult>T部分を動的型として渡す必要があります。ラムダ<Func<>>のパラメータとして動的に決定されたタイプを使用する方法?

Type変数を渡すことはできないか、またはtypeofをジェネリックで使用することはできないようです。

// (f => f.Baz == 1) 
Type theType = Type.GetType("Foo"); 
ParameterExpression pe = Expression.Parameter(theType, "f"); 
Expression left = Expression.Property(pe, theType.GetProperty("Baz")); 
Expression right = Expression.Constant(1); 
Expression expr = Expression.Equal(left, right); 
// This works fine but uses a hard-coded type, which I won't know until runtime: 
// var lambda = Expression.Lambda<Func<Foo,bool>>(expr, new ParameterExpression[] { pe }).Compile(); 
var lambda = Expression.Lambda<Func<theType, bool>>(expr, new ParameterExpression[] { pe }).Compile(); 

しかし、私はのFuncのT一部として変数theTypeを使用することはできません。基本的に私はこのような何かをしようとしています。これをどうすれば解決できますか?

答えて

1

できません。例えば

、C#では、あなたがすることはできません:

Type t = typeof(int); 
List<t> list = new List<t>(); 

または

object list = new List<t>(); 

あなたはリフレクションを使用しますが、その後はobjectにリストを配置する必要がない限り

、とのことができます。リフレクションを通してのみ使用してください。

Func<>object(またはdynamic)に保存できますが、これ以上保存することはできません。

あなたがすることはいつもFunc<object, bool>を返して、オブジェクトをラムダ関数のdesideredタイプにキャストします(Expression.Convert(pe, theType)を使用してください)。

それとも、動的な使用することができます(いくつかのベンチマーク(StopWatch.Ticksで、唯一の割合のためにそれらを見て)「ではない本物として」取るべき

// lambda == Func<Foo, bool> 
dynamic lamdba = Expression.Lambda(expr, new ParameterExpression[] { pe }).Compile(); 

bool res = lambda(myvalue); 

または

// lambda == Func<Foo, bool> 
Delegate lamdba = Expression.Lambda(expr, new ParameterExpression[] { pe }).Compile(); 
bool res = (bool)lambda2.DynamicInvoke(t); 

をリリースモード+デバッグを開始しない+無駄なサイクルが発生して「ホット」になる):

236384685 dynamic 
    56773593 Func<object, bool> + cast 
10556024247 DynamicInvoke 

メモとして、 Func<Foo, bool>は同じスピードを持つので、余分なキャストでスピードが失われることはありません。

ここにコードが表示されますhttp://ideone.com/qhnVP3

関連する問題

 関連する問題