것이 가장 좋은 방법인지 모르겠어요,하지만 당신은 그런 일 할 수있는 :
이
public Expression<Func<TContainer,bool>> CreatePredicate<TContainer,TMember>(
Expression<Func<TContainer,TMember>> getMemberExpression,
Expression<Func<TMember,bool>> memberPredicateExpression)
{
ParameterExpression x = Expression.Parameter(typeof(TContainer), "x");
return Expression.Lambda<Func<TContainer, bool>>(
Expression.Invoke(
memberPredicateExpression,
Expression.Invoke(
getMemberExpression,
x)),
x);
}
사용법 :
이
var expr = CreatePredicate(
(Foo f) => f.Bar,
bar => bar % 2 == 0);
결과 :
x => Invoke(bar => ((bar % 2) == 0), Invoke(f => f.Bar, x))
내 생각을 x => x.Bar % 2 == 0
과 같은 것을 얻는 편이 낫겠지 만, 아마도 더 어려울 것입니다 ...
편집 :
public Expression<Func<TContainer,bool>> CreatePredicate<TContainer,TMember>(
Expression<Func<TContainer,TMember>> getMemberExpression,
Expression<Func<TMember,bool>> memberPredicateExpression)
{
return CombineExpressionVisitor.Combine(
getMemberExpression,
memberPredicateExpression);
}
class CombineExpressionVisitor : ExpressionVisitor
{
private readonly ParameterExpression _parameterToReplace;
private readonly Expression _replacementExpression;
private CombineExpressionVisitor(ParameterExpression parameterToReplace, Expression replacementExpression)
{
_parameterToReplace = parameterToReplace;
_replacementExpression = replacementExpression;
}
public static Expression<Func<TSource, TResult>> Combine<TSource, TMember, TResult>(
Expression<Func<TSource, TMember>> memberSelector,
Expression<Func<TMember, TResult>> resultSelector)
{
var visitor = new CombineExpressionVisitor(
resultSelector.Parameters[0],
memberSelector.Body);
return Expression.Lambda<Func<TSource, TResult>>(
visitor.Visit(resultSelector.Body),
memberSelector.Parameters);
}
protected override Expression VisitParameter(ParameterExpression parameter)
{
if (parameter == _parameterToReplace)
return _replacementExpression;
return base.VisitParameter(parameter);
}
}
그것은 다음 식을 제공합니다 : 실제로는 식의 방문자와 그렇게 어렵지 않았다
f => ((f.Bar % 2) == 0)
감사합니다 - 나는 실제로 무엇을거야을 고 말했다. 이것은 좋은 출발점이 될 수도 있습니다. – smartcaveman
@ 토마스, 좋아,이게 내가 생각한거야 : 당신이 제안한 것을해라. 그러나 먼저 LambdaExpression의 ParameterExpressions를 비교하여 중복 된 매개 변수 이름이 없는지 확인한다. 그런 다음'ExpressionVisitor'가'ExpressionType.Invoke'를 방문하여 인수를 선택하고 각 매개 변수 항목을 대체하는 인수 값을 사용하여 새로운'getMemberExpression.Body'를 만듭니다. 그런 다음 LambdaExpression의 본문을 반환합니다. 이게 너 한테 어떻게 들리는거야? – smartcaveman
@smartcaveman, 나는 결국 Invoke를 전혀 필요로하지 않는 ExpressionVisitor 솔루션을 작성했습니다. 내 업데이트 된 답변보기 –