【发布时间】:2014-11-04 15:43:56
【问题描述】:
这一定很简单。但无论如何我都会问它,因为我认为其他人也会为此而苦苦挣扎。为什么以下简单的 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-value 而总是第一个呢?
我知道我可以用这条附加线修复它:
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))
{
// ...
}
【问题讨论】:
-
当你将变量作为参数传递给函数时,它是按值传递的。
-
如此简单的一段代码,却有着如此复杂的副作用。
-
天哪,你从 The Actual Raymond Chen™ 那里得到了答案!
-
@s.m. Raymond Chen 的评论和 Jon Skeet 的回答。
标签: c# .net linq lazy-evaluation