编辑
2025-09-28
C#
00

目录

延迟执行(Deferred Execution)
示例1:延迟执行
示例2:延迟执行的陷阱
即时执行(Immediate Execution)
示例3:即时执行
示例4:聚合函数和即时执行
总结

在C#中,LINQ(语言集成查询)是一个强大的特性,它允许开发者以声明式的方式对数据进行查询和操作。LINQ查询可以应用于各种数据源,包括集合、数据库以及XML文件。理解LINQ查询的执行方式是非常重要的,因为它影响着查询的性能和行为。在LINQ中,查询执行主要分为两种类型:延迟执行(Deferred Execution)和即时执行(Immediate Execution)。

延迟执行(Deferred Execution)

延迟执行意味着LINQ查询的执行会被推迟,直到需要枚举结果时才会执行。这意味着查询本身只是定义了一个操作的计划,并不会立即从数据源中检索数据。

示例1:延迟执行

C#
using System.Diagnostics; namespace AppLinq { internal class Program { static void Main(string[] args) { List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; IEnumerable<int> query = numbers.Where(n => n > 3); // 此时查询还没有执行 Console.WriteLine("添加一个新数"); numbers.Add(6); // 修改原始数据 // 现在枚举查询结果,查询此时才执行 foreach (var number in query) { Console.WriteLine(number); } Console.ReadKey(); } } }

image.png

在上面的例子中,我们可以看到,即使在定义了查询之后修改了原始的集合,查询在执行时也会包含最新的数据。

示例2:延迟执行的陷阱

C#
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; IEnumerable<int> query = numbers.Select(n => n * 10); numbers.Clear(); // 清空原始数据 foreach (var number in query) { Console.WriteLine(number); // 不输出任何结果 }

在这个例子中,由于我们在枚举结果前清空了原始数据,所以即使定义了查询,我们也得不到任何结果。

即时执行(Immediate Execution)

与延迟执行不同,即时执行会立即从数据源中检索数据。这通常是通过调用像ToListToArrayCountMax等方法实现的,这些方法会迫使查询立即执行并返回结果。

示例3:即时执行

C#
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; List<int> immediateResult = numbers.Where(n => n > 3).ToList(); // 查询已经执行,并且结果已经存储在immediateResult中 Console.WriteLine("Before adding a new number to the list"); numbers.Add(6); // 修改原始数据 foreach (var number in immediateResult) { Console.WriteLine(number); // 输出 4, 5 }

image.png

在这个例子中,使用ToList迫使查询立即执行,即使后来原始数据发生了变化,结果也不会改变。

示例4:聚合函数和即时执行

C#
using System.Diagnostics; namespace AppLinq { internal class Program { static void Main(string[] args) { List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; int count = numbers.Where(n => n > 3).Count(); // 即时执行 // 查询已经执行,并且结果已经存储在count中 Console.WriteLine($"Count: {count}"); numbers.Add(6); // 修改原始数据 // count的值不会改变,因为查询已经执行 Console.WriteLine($"Count: {count}"); Console.ReadKey(); } } }

image.png

在这个例子中,使用Count方法导致查询立即执行,并返回了结果。

总结

理解LINQ查询的延迟执行和即时执行对于编写高效和正确的代码非常重要。延迟执行让查询更加灵活,但也可能带来意料之外的结果,尤其是当原始数据在查询定义后发生变化时。即时执行则可以提供稳定的结果,但可能会增加内存使用或导致不必要的性能开销。

在实际开发中,您应该根据具体情况选择合适的执行策略。通常,如果您需要对查询结果进行多次迭代,或者需要确保结果的一致性,那么即时执行可能是更好的选择。如果您希望查询能够适应数据的变化,并且对性能有严格要求,那么延迟执行可能更合适。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!