Using LINQ to Convert an IENumerable to a List

I see a lot of examples for LINQ where a foreach loop is used after the select to populate the result list. There are situations where you would want to use the foreach loop, mainly to take advantage of LINQ's deferred execution. However, most developers will not need, nor desire, to have deferred execute, especially for SQL based selects.

If you're not familiar with deferred execution, this is the method by which LINQ statements are executed. In essence, the returned IENumerable/IQueryable list from a LINQ statement has not executed, yet. After you use the LINQ statement (typically Select), you are returned an IENumerable/IQueryable list. However, this list has not been populated. When you call the foreach loop on the returned list, each item in the list is individually executed. This can have huge impacts if you use LINQ to query a database, or to query a collection which can be modified outside your immediate loop. Many people have posted problems on LINQ forums about the expected results of the foreach being different from the actual results.

I'm going to show you a simple way to force the entire list to execute and populate, with one simple command. 

Microsoft Explanation

Creates a List<T> from an IENumerable<T>

Example 1 demonstrates the typical LINQ select examples found online. This example demonstrates a list of names (possibly user names), and selecting only the names which start with "P".

Example 1

List<string> SampleList = new List<string>() { "Mary", "Nancy", "Pete", "Ned", "Paul", "Bob", "Jim", "Maria" };
List<string> FilteredList = new List<string>();

// get the list of names that start with "P"
var query = from x in SampleList
            where x.StartsWith("P")
            select x;

// pop the filtered list
foreach (var result in query)
    FilteredList.Add(result);

 

If the SampleList were modifiable outside the immediate scope of this function (for example, as a property that other threads could access), it is very possible that the results of the select statement could change during the execution of the foreach loop.

The solution? Wrap the select with a call to the ToList extension:

Example 2 – The Solution

List<string> SampleList = new List<string>() { "Mary", "Nancy", "Pete", "Ned", "Paul", "Bob", "Jim", "Maria" };
List<string> FilteredList = new List<string>();

// get the list of names that start with "P"
FilteredList = (from x in SampleList
            where x.StartsWith("P")
            select x).ToList();

 

An even more consise way would be:

Example 3 – The Shorter Solution

List<string> SampleList = new List<string>() { "Mary", "Nancy", "Pete", "Ned", "Paul", "Bob", "Jim", "Maria" };
List<string> FilteredList = new List<string>();

// get the list of names that start with "P"
FilteredList = SampleList.Where(x => x.StartsWith("P")).ToList();

 

There are other ToX extensions, such as ToArray, ToDictionary, and ToLookup. These all perform the same immediate execution of the LINQ statement, returning the respective collection type.

If have questions, comments, or suggestion, please feel to post them in the LINQ Exchange Forum

GD Star Rating
loading...
GD Star Rating
loading...
Using LINQ to Convert an IENumerable to a List, 4.0 out of 5 based on 8 ratings
  • Share/Bookmark

No related posts.

Related posts brought to you by Yet Another Related Posts Plugin.

Leave a Reply