[c#] Freely convert between List<T> and IEnumerable<T>

How can I convert a List<MyObject> to an IEnumerable<MyObject> and then back again?

I want to do this in order to run a series of LINQ statements on the List, e. g. Sort()

This question is related to c# linq list ienumerable

The answer is


A List<T> is an IEnumerable<T>, so actually, there's no need to 'convert' a List<T> to an IEnumerable<T>. Since a List<T> is an IEnumerable<T>, you can simply assign a List<T> to a variable of type IEnumerable<T>.

The other way around, not every IEnumerable<T> is a List<T> offcourse, so then you'll have to call the ToList() member method of the IEnumerable<T>.


To prevent duplication in memory, resharper is suggesting this:

List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myList as List<string>() ?? myEnumerable.ToList();

.ToList() returns a new immutable list. So changes to listAgain does not effect myList in @Tamas Czinege answer. This is correct in most instances for least two reasons: This helps prevent changes in one area effecting the other area (loose coupling), and it is very readable, since we shouldn't be designing code with compiler concerns.

But there are certain instances, like being in a tight loop or working on an embedded or low memory system, where compiler considerations should be taken into consideration.


Converting List<T> to IEnumerable<T>

List<T> implements IEnumerable<T> (and many other such as IList<T>, ICollection<T>) therefore there is no need to convert a List back to IEnumerable since it already a IEnumerable<T>.

Example:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Person person1 = new Person() { Id = 1, Name = "Person 1" };
Person person2 = new Person() { Id = 2, Name = "Person 2" };
Person person3 = new Person() { Id = 3, Name = "Person 3" };

List<Person> people = new List<Person>() { person1, person2, person3 };

//Converting to an IEnumerable
IEnumerable<Person> IEnumerableList = people;

You can also use Enumerable.AsEnumerable() method

IEnumerable<Person> iPersonList = people.AsEnumerable();

Converting IEnumerable<T> to List<T>

IEnumerable<Person> OriginallyIEnumerable = new List<Person>() { person1, person2 };
List<Person> convertToList = OriginallyIEnumerable.ToList();

This is useful in Entity Framework.


A List<T> is already an IEnumerable<T>, so you can run LINQ statements directly on your List<T> variable.

If you don't see the LINQ extension methods like OrderBy() I'm guessing it's because you don't have a using System.Linq directive in your source file.

You do need to convert the LINQ expression result back to a List<T> explicitly, though:

List<Customer> list = ...
list = list.OrderBy(customer => customer.Name).ToList()

A List<T> is an IEnumerable<T>, so actually, there's no need to 'convert' a List<T> to an IEnumerable<T>. Since a List<T> is an IEnumerable<T>, you can simply assign a List<T> to a variable of type IEnumerable<T>.

The other way around, not every IEnumerable<T> is a List<T> offcourse, so then you'll have to call the ToList() member method of the IEnumerable<T>.


Aside: Note that the standard LINQ operators (as per the earlier example) don't change the existing list - list.OrderBy(...).ToList() will create a new list based on the re-ordered sequence. It is pretty easy, however, to create an extension method that allows you to use lambdas with List<T>.Sort:

static void Sort<TSource, TValue>(this List<TSource> list,
    Func<TSource, TValue> selector)
{
    var comparer = Comparer<TValue>.Default;
    list.Sort((x,y) => comparer.Compare(selector(x), selector(y)));
}

static void SortDescending<TSource, TValue>(this List<TSource> list,
    Func<TSource, TValue> selector)
{
    var comparer = Comparer<TValue>.Default;
    list.Sort((x,y) => comparer.Compare(selector(y), selector(x)));
}

Then you can use:

list.Sort(x=>x.SomeProp); // etc

This updates the existing list in the same way that List<T>.Sort usually does.


To prevent duplication in memory, resharper is suggesting this:

List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myList as List<string>() ?? myEnumerable.ToList();

.ToList() returns a new immutable list. So changes to listAgain does not effect myList in @Tamas Czinege answer. This is correct in most instances for least two reasons: This helps prevent changes in one area effecting the other area (loose coupling), and it is very readable, since we shouldn't be designing code with compiler concerns.

But there are certain instances, like being in a tight loop or working on an embedded or low memory system, where compiler considerations should be taken into consideration.


A List<T> is already an IEnumerable<T>, so you can run LINQ statements directly on your List<T> variable.

If you don't see the LINQ extension methods like OrderBy() I'm guessing it's because you don't have a using System.Linq directive in your source file.

You do need to convert the LINQ expression result back to a List<T> explicitly, though:

List<Customer> list = ...
list = list.OrderBy(customer => customer.Name).ToList()

Aside: Note that the standard LINQ operators (as per the earlier example) don't change the existing list - list.OrderBy(...).ToList() will create a new list based on the re-ordered sequence. It is pretty easy, however, to create an extension method that allows you to use lambdas with List<T>.Sort:

static void Sort<TSource, TValue>(this List<TSource> list,
    Func<TSource, TValue> selector)
{
    var comparer = Comparer<TValue>.Default;
    list.Sort((x,y) => comparer.Compare(selector(x), selector(y)));
}

static void SortDescending<TSource, TValue>(this List<TSource> list,
    Func<TSource, TValue> selector)
{
    var comparer = Comparer<TValue>.Default;
    list.Sort((x,y) => comparer.Compare(selector(y), selector(x)));
}

Then you can use:

list.Sort(x=>x.SomeProp); // etc

This updates the existing list in the same way that List<T>.Sort usually does.


A List<T> is an IEnumerable<T>, so actually, there's no need to 'convert' a List<T> to an IEnumerable<T>. Since a List<T> is an IEnumerable<T>, you can simply assign a List<T> to a variable of type IEnumerable<T>.

The other way around, not every IEnumerable<T> is a List<T> offcourse, so then you'll have to call the ToList() member method of the IEnumerable<T>.


Aside: Note that the standard LINQ operators (as per the earlier example) don't change the existing list - list.OrderBy(...).ToList() will create a new list based on the re-ordered sequence. It is pretty easy, however, to create an extension method that allows you to use lambdas with List<T>.Sort:

static void Sort<TSource, TValue>(this List<TSource> list,
    Func<TSource, TValue> selector)
{
    var comparer = Comparer<TValue>.Default;
    list.Sort((x,y) => comparer.Compare(selector(x), selector(y)));
}

static void SortDescending<TSource, TValue>(this List<TSource> list,
    Func<TSource, TValue> selector)
{
    var comparer = Comparer<TValue>.Default;
    list.Sort((x,y) => comparer.Compare(selector(y), selector(x)));
}

Then you can use:

list.Sort(x=>x.SomeProp); // etc

This updates the existing list in the same way that List<T>.Sort usually does.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to linq

Async await in linq select How to resolve Value cannot be null. Parameter name: source in linq? What does Include() do in LINQ? Selecting multiple columns with linq query and lambda expression System.Collections.Generic.List does not contain a definition for 'Select' lambda expression join multiple tables with select and where clause LINQ select one field from list of DTO objects to array The model backing the 'ApplicationDbContext' context has changed since the database was created Check if two lists are equal Why is this error, 'Sequence contains no elements', happening?

Examples related to list

Convert List to Pandas Dataframe Column Python find elements in one list that are not in the other Sorting a list with stream.sorted() in Java Python Loop: List Index Out of Range How to combine two lists in R How do I multiply each element in a list by a number? Save a list to a .txt file The most efficient way to remove first N elements in a list? TypeError: list indices must be integers or slices, not str Parse JSON String into List<string>

Examples related to ienumerable

How to concatenate two IEnumerable<T> into a new IEnumerable<T>? Remove an item from an IEnumerable<T> collection Converting from IEnumerable to List Shorter syntax for casting from a List<X> to a List<Y>? filtering a list using LINQ How to check if IEnumerable is null or empty? Convert from List into IEnumerable format IEnumerable vs List - What to Use? How do they work? Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.IEnumerable<> Convert DataTable to IEnumerable<T>