这一定很简单。但是我还是要问这个问题,因为我认为其他人也会为此而挣扎。为什么以下简单的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 ,因此我们可以看到更改。

10-06 05:13
查看更多