为什么使用PredicateBuilder的代码不起作用?

TCM*_*TCM 6 c# linq

为什么我的清单没有退回任何东西?

 class Program
    {
        static void Main(string[] args)
        {
            var list = new List<string>{ "apple" , "mango" , "chickoo", "kiwi" };
            var searchWord = new List<string>{ "a" };

            var predicate = PredicateBuilder.False<string>();

            foreach(var word in searchWord)
            {
                predicate.Or(p => p.Contains(word));
            }

           var qry = list.Where(predicate.Compile());

           foreach (var item in qry)
           {
               Console.WriteLine(item);
           }

           Console.Read();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我正在使用Joseph Albahari的PredicateBuilder.

Ahm*_*eed 18

您需要将结果分配给predicate变量:

predicate = predicate.Or(p => p.Contains(word));
Run Code Online (Sandbox Code Playgroud)

PredicateBuilder页面还强调一个重要的问题:

循环中的临时变量需要避免外部变量陷阱,其中为foreach循环的每次迭代捕获相同的变量.

因此,您的代码应该类似于:

        foreach(var word in searchWord)
        {
            var temp = word;
            predicate = predicate.Or(p => p.Contains(temp));
        }
Run Code Online (Sandbox Code Playgroud)


Ani*_*Ani 5

这里有两个问题:

  1. Or扩展的方法就不会发生变异现有的表达式树-它返回一个新的.表达式树通常是不可变的.
  2. 您正在关闭循环变量.要了解这是一个问题的原因,请参阅关闭被认为有害的循环变量.

尝试:

foreach(var word in searchWord)
{
    var wordCopy = word;
    predicate = predicate.Or(p => p.Contains(wordCopy));
}
Run Code Online (Sandbox Code Playgroud)

甚至更好:

var predicate = searchWord.Aggregate(PredicateBuilder.False<string>(),
                   (predSoFar, word) => predSoFar.Or(p => p.Contains(word)));
Run Code Online (Sandbox Code Playgroud)