Is this a Visual Studio bug or .NET runtime bug?
Consider the following code:
public class DoWork
{
public void Run()
{
List<Entity> items = new List<Entity>();
items.Add(new Entity { Name = "1" });
items.Add(new Entity { Name = "12" });
int maxLength = items.Max(p => p.Name.Length);
var temp = items.Where(p => p.Name.Length == maxLength);
do
{
this.Import(items);
temp = items.Where(p => p.Name.Length < maxLength && !p.IsImported);
// If you use a quick watch, you will see just one item correctly
maxLength = temp.Count() > 0 ? temp.Max(p => p.Name.Length) : 0;
// Here, when you set maxLength, you will notice that VS will break into lambda body above
// Here temp is empty, but if you use the final ToList it works:
// temp = items.Where(p => p.Name.Length < maxLength && !p.IsImported).ToList();
}
while (maxLength > 0);
}
private void Import(List<Entity> items)
{
items.Last().IsImported = true;
}
}
It’s a strange behavior and it’s the first time I see something like that.
Is it a bug?
2
Answers
No it’s not a bug –
temp
is just a query that does not get executed until you actually use it. So when you do:The query actually gets executed twice. If you want to run the full query you could do:
But since you are looping and running multiple similar queries it’s not completely clear if running the queries twice is actually a problem.
The statement
temp = items.Where(...)
only sets up a query but does not evaluate it; however, bothCount()
andMax()
will. Note thattemp
is not a collection!You could use this instead to enumerate the list only once: