c#表达式树绑定

本文关键字:绑定 表达式 | 更新日期: 2023-09-27 18:11:16

所以我要做的是使用表达式树将谓词应用于集合中的每个值(读取map或list.All(谓词))。似乎我没有获得绑定到All提供的值的谓词的输入参数,并且我有点卡住了。以下是我正在使用的代码(使用linqpad)::

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();
}

谢谢,对不起,如果这是回答在另一个问题(我找了一段时间)。

c#表达式树绑定

这确实有效,但我必须将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();
}