none
LINQ在foreach循环中存在的问题 RRS feed

  • 问题

  • 代码如下
      List<string> table = new List<string>();
      table.Add("a");
      table.Add("b");
      table.Add("c");
      table.Add("aa");
      table.Add("bb");
      table.Add("cc");
      table.Add("aabb");
      table.Add("aacc");
      table.Add("bbcc");
      table.Add("aabbcc");

      string[] keys = new string[] { "a", "b", "c" };

      IEnumerable<string> sql = table;

      foreach (string key in keys)
      {
      sql = sql.Where(s => s.Contains(key));
      }

      int count = sql.Count();

    我想要的结果应该是count为1,找到的那个字符串是aabbcc

    但是实际结果是5,返回的是c, cc, aacc, bbcc, aabbcc, 也就是只有最后一个条件满足了
    我调试了一下发现,在第3次进入foreach循环体时,sql仍然还有10个对象,似乎前2次的WHERE都没有生效

    然后我将foreach换成了
    for (int i = 0; i < keys.Length; i++)
    {
      string key = keys[i];
      sql = sql.Where(s => s.Contains(key));
    }

    结果就是 count为1了,正确了


    谁知道这是为什么吗
    2012年4月15日 10:13

答案

  • 因為你的sql = sql.Where是放在loop裡面,所以離開loop只會保留最後一次執行的結果,或許你可以利用下列的程式碼來觀察之間的變化。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                List<string> table = new List<string>();
                table.Add("a");
                table.Add("b");
                table.Add("c");
                table.Add("aa");
                table.Add("bb");
                table.Add("cc");
                table.Add("aabb");
                table.Add("aacc");
                table.Add("bbcc");
                table.Add("aabbcc");
    
                string[] keys = new string[] { "a", "b", "c" };
    
                IEnumerable<string> sql = table;
    
                foreach (string key in keys)
                {
                    Console.WriteLine(string.Format("Key:{0}",key));
                    sql = sql.Where(s => s.Contains(key));
                    foreach (string s in sql)
                    {
                        Console.WriteLine(s);
                    }
                }
    
                //int count = sql.Count();
                Console.ReadKey();
            }
        }
    }
    


    以上說明若有錯誤請指教,謝謝。
    http://www.dotblogs.com.tw/terrychuang/

    2012年4月16日 2:32

全部回复

  • 您好,这不是foreach的问题,您的foeach语句中,每循环一次,都给sql赋了一个新值,到最后循环结束时,sql的值为你最后一个赋的值,故你的sql为

    sql.Where(s=>s.Contains("c"));

    所以每一个包含"c"的字符串都被查询了出来。你的for语句和你的foreach语句是一样的,也不应该返回1。

    Allen Li [MSFT]
    MSDN Community Support | Feedback to us

    2012年4月16日 1:56
    版主
  • 因為你的sql = sql.Where是放在loop裡面,所以離開loop只會保留最後一次執行的結果,或許你可以利用下列的程式碼來觀察之間的變化。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                List<string> table = new List<string>();
                table.Add("a");
                table.Add("b");
                table.Add("c");
                table.Add("aa");
                table.Add("bb");
                table.Add("cc");
                table.Add("aabb");
                table.Add("aacc");
                table.Add("bbcc");
                table.Add("aabbcc");
    
                string[] keys = new string[] { "a", "b", "c" };
    
                IEnumerable<string> sql = table;
    
                foreach (string key in keys)
                {
                    Console.WriteLine(string.Format("Key:{0}",key));
                    sql = sql.Where(s => s.Contains(key));
                    foreach (string s in sql)
                    {
                        Console.WriteLine(s);
                    }
                }
    
                //int count = sql.Count();
                Console.ReadKey();
            }
        }
    }
    


    以上說明若有錯誤請指教,謝謝。
    http://www.dotblogs.com.tw/terrychuang/

    2012年4月16日 2:32