Freely convert between List<T> and IEnumerable<T>

C#LinqListIenumerable

C# Problem Overview


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()

C# Solutions


Solution 1 - C#

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

Solution 2 - C#

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>.

Solution 3 - C#

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()

Solution 4 - C#

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.

Solution 5 - C#

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.

Solution 6 - C#

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTK.View Question on Stackoverflow
Solution 1 - C#Tamas CzinegeView Answer on Stackoverflow
Solution 2 - C#Frederik GheyselsView Answer on Stackoverflow
Solution 3 - C#Dan BerindeiView Answer on Stackoverflow
Solution 4 - C#Marc GravellView Answer on Stackoverflow
Solution 5 - C#NipunaView Answer on Stackoverflow
Solution 6 - C#TamusJRoyceView Answer on Stackoverflow