2011-10-26 2 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) 사용).

또는 당신이 사용할 수있는 동적 :

// 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); 

는 (전용 비율 그들을 보면, StopWatch.Ticks에) 몇 가지 벤치 마크 "와 같은 진짜"촬영하려면 (릴리스 모드 + 디버깅하지 않고 시작 + 쓸모없는 사이클로 인해 "핫") :

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

참고로, Func<Foo, bool>은 같은 속도를 가지므로 여분의 캐스트에서 속도가 손실되지 않습니다.

여기에서 코드를 볼 수 있습니다. http://ideone.com/qhnVP3

관련 문제