合并数组中的多个LINQ表达式
时间:2020-03-06 15:00:25 来源:igfitidea点击:
我试图结合这样的功能列表。
我有这个:
Func<int, bool>[] criteria = new Func<int, bool>[3]; criteria[0] = i => i % 2 == 0; criteria[1] = i => i % 3 == 0; criteria[2] = i => i % 5 == 0;
我想要这个:
Func<int, bool>[] predicates = new Func<int, bool>[3]; predicates[0] = i => i % 2 == 0; predicates[1] = i => i % 2 == 0 && i % 3 == 0; predicates[2] = i => i % 2 == 0 && i % 3 == 0 && i % 5 == 0;
到目前为止,我有以下代码:
Expression<Func<int, bool>>[] results = new Expression<Func<int, bool>>[criteria.Length]; for (int i = 0; i < criteria.Length; i++) { results[i] = f => true; for (int j = 0; j <= i; j++) { Expression<Func<int, bool>> expr = b => criteria[j](b); var invokedExpr = Expression.Invoke( expr, results[i].Parameters.Cast<Expression>()); results[i] = Expression.Lambda<Func<int, bool>>( Expression.And(results[i].Body, invokedExpr), results[i].Parameters); } } var predicates = results.Select(e => e.Compile()).ToArray(); Console.WriteLine(predicates[0](6)); // Returns true Console.WriteLine(predicates[1](6)); // Returns false Console.WriteLine(predicates[2](6)); // Throws an IndexOutOfRangeException
有人知道我在做什么错吗?
解决方案
据我所知,这是个猜测,但这似乎可以解决此问题:
Func<int, bool>[] criteria = new Func<int, bool>[3]; criteria[0] = i => i % 2 == 0; criteria[1] = i => i % 3 == 0; criteria[2] = i => i % 5 == 0; Expression<Func<int, bool>>[] results = new Expression<Func<int, bool>>[criteria.Length]; for (int i = 0; i < criteria.Length; i++) { results[i] = f => true; for (int j = 0; j <= i; j++) { int ii = i; int jj = j; Expression<Func<int, bool>> expr = b => criteria[jj](b); var invokedExpr = Expression.Invoke(expr, results[ii].Parameters.Cast<Expression>()); results[ii] = Expression.Lambda<Func<int, bool>>(Expression.And(results[ii].Body, invokedExpr), results[ii].Parameters); } } var predicates = results.Select(e => e.Compile()).ToArray();
关键是引入" ii"和" jj"(也许只有一个问题,我没有尝试)。我认为我们是在lambda中捕获一个可变变量,因此,当我们最终引用它时,我们会看到后来突变的值,而不是原始值。
无需提取表达式...
Func<int, bool>[] criteria = new Func<int, bool>[3]; criteria[0] = i => i % 2 == 0; criteria[1] = i => i % 3 == 0; criteria[2] = i => i % 5 == 0; Func<int, bool>[] predicates = new Func<int, bool>[3]; predicates[0] = criteria[0]; for (int i = 1; i < criteria.Length; i++) { //need j to be an unchanging int, one for each loop execution. int j = i; predicates[j] = x => predicates[j - 1](x) && criteria[j](x); } Console.WriteLine(predicates[0](6)); //True Console.WriteLine(predicates[1](6)); //True Console.WriteLine(predicates[2](6)); //False