2011-10-13 99 views
2

那么,我试图做的是使用表达式树的集合中的谓词应用到每个值(读地图或list.All(谓语))。看来,我没有得到的输入参数绑定到所有提供的值谓词,我有点卡住了。下面是我用::C#表达式树绑定

public class SomeType 
{ 
    public IEnumerable<bool> Collection { get; set; } 
} 

void Main() 
{ 
    var list = new SomeType { 
    Collection = new List<bool> { true, true, true } 
    }; 
    var functor = Compiler((SomeType t) => t.Collection, (bool x) => x); 
    functor(list).Dump(); 
} 

MethodInfo FindMethod<TInput>(Type location, string name) 
{ 
    var handle = location 
     .GetMethods(BindingFlags.Static | BindingFlags.Public) 
     .Where(method => method.Name == name).First(); 

    return handle.MakeGenericMethod(typeof(TInput)); 
} 

Predicate<TObject> Compiler<TObject, TProperty>(
    Expression<Func<TObject, IEnumerable<TProperty>>> selector, 
    Expression<Predicate<TProperty>> predicate) 
{ 
    var query = FindMethod<TProperty>(typeof(Enumerable), "All"); 
    var expression = Expression.Call(query, 
     new Expression[] { 
      Expression.Invoke(selector, selector.Parameters), 
      Expression.Lambda<Func<TProperty, bool>>(predicate.Body, 
         Expression.Parameter(typeof(TProperty))), 
     });   

    return Expression.Lambda<Predicate<TObject>>(expression, 
     selector.Parameters).Compile(); 
} 

感谢和抱歉工作,如果这是在另外一个问题(我看了一会儿)回答的代码(使用linqpad)。

回答

1

这并不工作,但我不得不改变Predicate<TObject>Func<TObject, bool>。如果你想我可以尝试改回它。

static Predicate<TObject> Compiler<TObject, TProperty>(
    Expression<Func<TObject, IEnumerable<TProperty>>> selector, 
    Expression<Func<TProperty, bool>> predicate) 
{ 
    var query = FindMethod<TProperty>(typeof(Enumerable), "All"); 
    var expression = Expression.Call(
     query, 
     Expression.Invoke(selector, selector.Parameters), 
     predicate); 

    return Expression 
     .Lambda<Predicate<TObject>>(expression, selector.Parameters) 
     .Compile(); 
} 

在5分钟后......如果你真的想用Predicate<TObject> ...

static Predicate<TObject> Compiler<TObject, TProperty>(
    Expression<Func<TObject, IEnumerable<TProperty>>> selector, 
    Expression<Predicate<TProperty>> predicate) 
{ 
    var query = FindMethod<TProperty>(typeof(Enumerable), "All"); 

    var predicateAsFunc = Expression.Lambda<Func<TProperty, bool>>(
     predicate.Body, 
     predicate.Parameters); 

    var expression = Expression.Call(
     query, 
     Expression.Invoke(selector, selector.Parameters), 
     predicateAsFunc); 

    return Expression 
     .Lambda<Predicate<TObject>>(expression, selector.Parameters) 
     .Compile(); 
} 
+0

我不知道为什么我不只是传递谓词参数(叹气)。是的,我必须使用谓词,因为它已经严重依赖到代码的其余部分。谢谢! – Bashwork

+0

@Bashwork如果你需要我缩短一点。现在我重复使用'select.Parameters'(少一行) – xanatos