Refer to the LinqPad script below.
When performing the workflow, I take the following set of tasks HasRunfrom the collection (IEnumerable). Iterating over the result set of the Linq query, I change the task to HasRun = true. Debugging shows that initially I received the expected subset of four objects, however, after the subset has been checked, the enumeration suddenly proceeds to the next subset, and the foreach loop continues through this set, and then to the next, etc.
Therefore, when I expect to repeat the iteration four times, it continues until all three subsets (9 elements) are repeated. This is easy to solve with the .ToList()enumerated one, but I wonder if this is intentional behavior.
In Googling, I found references to the “unpredictable behavior” of iteration variables, this old post is one example on which @jon skeet commented , but the latest C # specification (section 8.8.4) does not mention unpredictable behavior, it just mentions problems with assignment, increment and decrease:
A compilation error if the built-in operator tries to change the iteration variable (through the assignment of either ++ and the operators) or pass the iteration variable as the parameter ref or out.
Is this design behavior?
void Main()
{
List<Foo> foos = new List<UserQuery.Foo>
{
new Foo{ SetNbr = 1, HasRun = false },
new Foo{ SetNbr = 1, HasRun = false },
new Foo{ SetNbr = 1, HasRun = false },
new Foo{ SetNbr = 1, HasRun = false },
new Foo{ SetNbr = 2, HasRun = false },
new Foo{ SetNbr = 2, HasRun = false },
new Foo{ SetNbr = 3, HasRun = false },
new Foo{ SetNbr = 3, HasRun = false },
new Foo{ SetNbr = 3, HasRun = false }
};
var firstNotRunGroup = foos.Where(a => a.SetNbr == (foos.Where(f => f.HasRun == false).Min(f => f.SetNbr)));
foreach (Foo foo in firstNotRunGroup)
{
foo.HasRun = true;
Console.WriteLine(foo.SetNbr);
}
}
class Foo
{
public int SetNbr { get; set; }
public bool HasRun { get; set; }
}
Conclusion:
1
1
1
1
2
2
3
3
3