C# 表达式树绑定(bind)

标签 c# linq expression-trees

所以我想做的是使用表达式树将谓词应用于集合中的每个值(读取映射或 list.All(predicate))。看来我没有获得绑定(bind)到 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();
}

如果这个问题在另一个问题中得到了回答(我找了一会儿),则表示感谢和抱歉。

最佳答案

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

关于C# 表达式树绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7759346/

相关文章:

c# - 从 C# 执行 python

c# - 在 C# 中,我们可以对接口(interface)使用 protected 访问修饰符吗?

c# - 使用 Entity Framework 选择 DBSet 中的行

c# - 如何使用 Linq 表达式树从 Span<T> 中获取值?

c# - unity NavMeshPath 改变和重新分配

c# - 如何使用 C# 从 java 进程获取带有参数的 ProcessStartInfo?

c# - 如何用Linq SqlQuery 构造MySqlParamter?

c# - 从 LINQ to SQL 查询加载 DataGridView

c# - Expression.Block() 可以在 lambda 闭包中返回一个值吗?

c# - 如何构建具有特定签名的表达式?