linq max懒惰的评价

时间:2012-07-18 14:29:41

标签: c# linq lazy-evaluation

我在理解延迟评估与linq Max运算符的关系时遇到了一些麻烦。

这是我的代码:

        var someList = new List<someType>
        {
            new someType { decimalValue = 32 }
        };

line1: var valA = someList.Any() ? someList.Max(s => s.decimalValue) : 0.0M;

line2: var valB = someList.Any() ? someList.Max(s => s.decimalValue) : 0.0M;

line3: var valC = valB;

当单步执行代码时,我会看到以下行为:

第1行执行后,valA = 0, valB = 0, valC = 0

第2行执行后,valA = 32, valB = 0, valC = 0

执行第3行后,valA = 32, valB = 32, valC = 32

为什么valA仅在valB被分配后显示一个值,为什么valB仅在分配valC时显示一个值?

下面是我的调试器的屏幕截图。我想我的IDE必须有一些非标准的东西。

IDE image http://toastermagic.co.uk/images/linqMax.png

2 个答案:

答案 0 :(得分:1)

Max运算符立即执行,根本不会延迟。您所看到的只是调试器的正常行为。当它突出显示一行时,意味着“我即将运行此行”,而不是“我刚刚运行此行”。您总是需要在“下一行”上查看给定代码行的结果。

似乎你已经解释了这一点。你看到所有的变化(这不应该只是LINQ特定的)这一事实可能意味着你的源代码和可执行文件有点不同步。你应该对解决方案进行清理和重新设计,然后一切都应该没问题。我猜你对源代码进行了一些小的修改,这些修改在构建中没有得到正确的选择,所以可执行文件和源代码中的行号都是一个。

如果某些内容真的非常错误,您可以尝试将代码完全移动到新项目(如果您的代码库足够小),以试图摆脱任何损坏或损坏的文件/设置导致此问题。

答案 1 :(得分:0)

无法复制:

    static void Main(string[] args)
    {
        var data = (from n in Enumerable.Range(0, 10)
                    select new { value = (decimal)n })
                   .ToList();

        var valA = data.Any() ? data.Max(s => s.value) : 0.0M;
        Console.WriteLine("A = {0}, B = {1}, C = {2}", valA, 0, 0);

        var valB = data.Any() ? data.Max(s => s.value) : 0.0M;
        Console.WriteLine("A = {0}, B = {1}, C = {2}", valA, valB, 0);

        var valC = valB;
        Console.WriteLine("A = {0}, B = {1}, C = {2}", valA, valB, valC);

        Console.ReadLine();
    }

按预期工作。

看起来是对调试器的误读。