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:

image

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.

1 Comment

Comments have been disabled for this content.