views:

11875

answers:

4

How can I convert a List to an IEnumerable and back again.

The reason I want to do this is to run a series of LINQ statements on the List i.e. sort etc

+19  A: 
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();
DrJokepu
Beware however that myEnumarable is the same object instance as myList, but listAgain is not the same object instance as myEnumerable. Depending on what you want to do and what myEnumerable is, "List<string> listAgain = myEnumerable as List<string>;" might be better.
ChrisW
Chrisw: Oh yes, you're right of course, but the IEnumerable<T> interface is immutable so it will not cause problems in that direction and casting back just feels *dirty* when you have a function that will take care of type safety.
DrJokepu
You also could just use the original myList object. (I guess I don't really get the question)
sth
It's just that if he edits myList then he would be editing myEnumrable, but if he edits listAgain then he wouldn't be editing myEnumerable.
ChrisW
+2  A: 

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.

Marc Gravell
A slight correction to this statement: the standard LINQ operators don't change the existing list; instead, they create a new IEnumerable that contains the logic necessary for doing their work. However, this logic isn't actually executed until the IEnumerator is requested.
Vojislav Stojkovic
@Vojislav - I was meaning in the context of the earlier example ending with `ToList` - I will clarify, though.
Marc Gravell
+5  A: 

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

Frederik Gheysels
Technically, ToList is a member method of System.Linq.Enumerable
David B
I think you can just cast IEnumerable on List as David say it is it.
abatishchev
+1  A: 

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