2009-06-23 122 views
7

我發現一些很奇怪的東西(我想!)。如果我嘗試在yes()方法中放置一個斷點,它將永遠不會在執行該函數時暫停程序。如果我嘗試對其他任何代碼行執行相同的操作,它將按預期工作。這是一個錯誤,還是有東西是逃避我?調試器不打中斷點

過濾器將返回2個對象,除調試器外,一切似乎都按預期工作。

private void Form1_Load(object sender, EventArgs e) { 
    List<LOL> list = new List<LOL>(); 
    list.Add(new LOL()); 
    list.Add(new LOL()); 

    IEnumerable<LOL> filter = list.Where(
     delegate(LOL lol) { 
      return lol.yes(); 
     } 
    ); 

    string l = ""; <------this is hit by the debugger 
} 

class LOL { 
    public bool yes() { 
     bool ret = true; <---------this is NOT hit by the debugger 
     return ret; 
    } 
} 
+3

請記住,像Where這樣的查詢方法的結果是_an代表query_的對象。這不是查詢的_results_。這是查詢_本身。直到你接着說「嘿問,你的結果是什麼?」該查詢實際執行。 – 2009-06-23 04:53:30

回答

16

Enumerable.Where是一個懶惰的運營商 - 直到你調用的東西,經過了IEnumerable返回的地方(即調用.ToList()就可以了),你的函數將不會被調用。

試着改變你的代碼,這一點,看看它是否被調用:

.... 
IEnumerable<LOL> filter = list.Where(
    delegate(LOL lol) { 
     return lol.yes(); 
    } 
).ToList(); 

string l = ""; 
2

你必須兌現列表。添加...

filter.ToList(); 

...在聲明後,你會打你的斷點。關於我見過的最好的討論是here。它做的懶惰評估比我能做得更好。

2

正如其他人所說,你剛剛定義了你的標準,但沒有要求執行。這被稱爲延遲加載(大家好,如果我錯了,請糾正我)。

在過濾器上運行foreach循環以查看會發生什麼。

2

喬納森是正確的。

嘗試運行此控制檯應用程序,並在指明的位置設置斷點以清楚地看到它。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<LOL> list = new List<LOL>(); 
      list.Add(new LOL()); 
      list.Add(new LOL()); 

      IEnumerable<LOL> filter = list.Where(
       delegate(LOL lol) 
       { 
        return lol.yes(); 
       } 
      ); 

      // Breakpoint #2 will not have been yet. 
      Console.Write("No Breakpoint"); // Breakpoint #1 
      // (Breakpoint #2 will now be hit.) 
      Console.Write("Breakpoint! " + filter.Count()); 
     } 

     class LOL 
     { 
      public bool yes() 
      { 
       bool ret = true; // Breakpoint #2 
       return ret; 
      } 

     } 

    } 
}