表达式树,listFoo.Where(lambda)抛出无效参数错误

时间:2012-05-30 13:28:03

标签: c# lambda

为什么以下代码抛出'...在'

处有一些无效的参数
    var qry = listFoo.Where(lambda);

我应该如何编写listFoo,以便通过传递谓词委托调用Where on it。我的整个代码如下所示,

    List<Foo> listFoo = new List<Foo>();

    ParameterExpression foo = Expression.Parameter(typeof(Foo), "foo");
    MemberExpression bar = Expression.PropertyOrField(foo, "Bar");
    ConstantExpression abc = Expression.Constant("abc", typeof(string)); 
    BinaryExpression test = Expression.Equal(bar, abc);

    Expression<Func<Foo, bool>> lambda = Expression.Lambda<Func<Foo, bool>>(test, foo);

    var qry = listFoo.Where(lambda);

2 个答案:

答案 0 :(得分:3)

因为您的列表不是IQueryable。你为什么不这样做?

var qry = listFoo.Where(foo => foo.Bar == "abc");

如果你不能这样做,请执行以下操作:

var qry = listFoo.Where(lambda.Compile()); //warning, slow performance

答案 1 :(得分:0)

IEnumerable上的LINQ扩展方法接受委托实例(Action<>Func<>个对象)。 Lambdas只是委托文字,因此在这种情况下它不会占用Expression<Func<>>因为你给它一个PLAN,而不是委托。这就是表达式,是一个如何处理一些数据的计划。 IQueryable接受表达式(并且编译器将委托文字视为Expression),以便它可以采取计划并合并(如果它们可以减少)。

对于IEnumerable,您需要在Compile()上调用Expression<Func<>>,然后才能将其传递给Where方法。但是,你可以这样做:

var qry = listFoo.AsQueryable().Where(lambda);

但是,这会为您提供IQueryable<Foo>结果,因此您仍需要执行AsEnumerableToListToArray等。