This must be something really simple. But i'm going to ask it anyway, because i think that others will also struggle with it. Why does following simple LINQ query is not executed always with the new variable-value instead of always using the first?
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();
}
In the commented sample it will enter the loop since the input ABC123
contains digits. But it will never leave it even if you enter something like ABC
since digits
still is 123
.
So why does the LINQ query not evaluate the new input
-value but always the first?
I know i could fix it with this additional line:
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
}
or - more elegant - by using the query directly in the loop:
while (input.Any(Char.IsDigit))
{
// ...
}
The difference is that you're changing the value of the input
variable, rather than the contents of the object that the variable refers to... so digits
still refers to the original collection.
Compare that with this code:
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());
}
This time, we're modifying the content of the collection that input
refers to - and as digits
is effectively a view over that collection, we get to see the change.
See more on this question at Stackoverflow