c# - LINQ 的延迟执行,但是如何呢?

标签 c# .net linq lazy-evaluation

这一定很简单。但我还是要问,因为我认为其他人也会为此而苦苦挣扎。为什么以下简单的 LINQ 查询并不总是使用新的变量值而不是总是使用第一个来执行?

static void Main(string[] args)
{
    Console.WriteLine("Enter something:");
    string input = Console.ReadLine();       // for example ABC123
    var digits = input.Where(Char.IsDigit);  // 123
    while (digits.Any())
    {
        Console.WriteLine("Enter a string which doesn't contain digits");
        input = Console.ReadLine();         // for example ABC
    }
    Console.WriteLine("Bye");
    Console.ReadLine();
}

在注释示例中,它将进入循环,因为输入 ABC123 包含数字。但它永远不会离开它,即使您输入类似 ABC 的内容,因为 digits 仍然是 123

那么,为什么 LINQ 查询不评估新的 input 值,而是始终评估第一个值?

我知道我可以用这条额外的线来修复它:

while (digits.Any())
{
    Console.WriteLine("Enter a string which doesn't contain digits");
    input = Console.ReadLine();          
    digits = input.Where(Char.IsDigit);  // now it works as expected
}

或者 - 更优雅 - 通过直接在循环中使用查询:

while (input.Any(Char.IsDigit))
{
    // ...
}

最佳答案

不同之处在于您更改的是 input 变量的值,而不是变量引用的对象的内容...所以 digits 仍指原始集合。

将其与这段代码进行比较:

List<char> input = new List<char>(Console.ReadLine());
var digits = input.Where(Char.IsDigit);  // 123
while (digits.Any())
{
    Console.WriteLine("Enter a string which doesn't contain digits");
    input.Clear();
    input.AddRange(Console.ReadLine());
}

这一次,我们正在修改 input 引用的集合的 content - 因为 digits 是一个有效的 View 收藏,我们可以看到变化。

关于c# - LINQ 的延迟执行,但是如何呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26739213/

相关文章:

C# HTMLAgilityPack 获取内容 &lt;script&gt;

c# - JavaScript 代码可以使网络浏览器上的文本闪烁一次

c# - ForEach 用于 Linq 中的列表列表

C# 修改字符串

c# - 如何在代码隐藏方法中访问 asp.net 按钮的 "Text"?

c# - 使用 Rhino Mocks 的 AAA 语法的严格模拟

c# - 使用 LINQ 和 mysqlconnection 遇到 fatal error

c# - 理解LINQ的Where/Take的基本原理

c# - 什么时候抛出异常更好,什么时候返回一些错误日志 'object' 更好?

c# - 如何使用反射创建高性能 .NET 类?