LINQ and IEnumerable may surprise you
Let us examine the following code snippet:
class Candidate { public string Name { get; set; } public bool Hired { get; set; } } class Program { static void Main(string[] args) { string[] names = { "Adam", "Byron", "Charles" }; var candidates = names.Select(n => new Candidate() { Name = n, Hired = false }); //now modify the value of each object foreach (var candidate in candidates) { candidate.Hired = true; } //noew print the value of each object foreach (var candidate in candidates) { Console.WriteLine(string.Format("Name:{0} Hired:{1}", candidate.Name, candidate.Hired)); } Console.Read(); } }
Basically, I create an IEnumerable<Candidate> from LINQ, and them loop through the results to modify each object. At the end, you might expect each candidate hired. Wrong! Here is the output:
What happened was LINQ actually delayed the object generation until enumeration. When we enumerate again to print the objects, LINQ actually generated a new set of objects. If you use ToList() to convert the IEnumerable to List, you will get the expected result:
var candidates = names.Select(n => new Candidate() { Name = n, Hired = false }).ToList();
ToList() will instantiate the objects immediately and the subsequent enumeration will be on the same objects. That is why you cannot find the .ForEach() extension method on IEnumerable<T>. You have to convert it to IList<T> to use the method.