这一定很简单。但是我还是要问这个问题,因为我认为其他人也会为此而挣扎。为什么以下简单的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))
{
// ...
}
最佳答案
区别在于您要更改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
所引用的集合的内容-由于digits
实际上是对该集合的 View ,因此我们可以看到更改。