2009-06-23 131 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; 
      } 

     } 

    } 
}