Свободно конвертировать между List <T>и IEnumerable <T> - PullRequest
101 голосов
/ 23 января 2009

Как я могу преобразовать List<MyObject> в IEnumerable<MyObject> и затем обратно?

Я хочу сделать это, чтобы запустить серию операторов LINQ в Списке, e. г. Sort()

Ответы [ 6 ]

145 голосов
/ 23 января 2009
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();
21 голосов
/ 23 января 2009

A List<T> - это IEnumerable<T>, поэтому на самом деле нет необходимости «конвертировать» List<T> в IEnumerable<T>. Поскольку List<T> является IEnumerable<T>, вы можете просто присвоить List<T> переменной типа IEnumerable<T>.

И наоборот, не каждый IEnumerable<T> является List<T> выходом, поэтому вам придется вызывать ToList() метод-член IEnumerable<T>.

9 голосов
/ 17 февраля 2010

A List<T> уже является IEnumerable<T>, поэтому вы можете запускать операторы LINQ непосредственно в переменной List<T>.

Если вы не видите методы расширения LINQ, такие как OrderBy() Я предполагаю, что это потому, что в вашем исходном файле нет директивы using System.Linq.

Вам необходимо преобразовать результат выражения LINQ обратно в List<T> явно, хотя:

List<Customer> list = ...
list = list.OrderBy(customer => customer.Name).ToList()
5 голосов
/ 23 января 2009

В сторону: обратите внимание, что стандартные операторы LINQ (как в предыдущем примере) не изменяют существующий список - list.OrderBy(...).ToList() создаст новый список на основе переупорядоченной последовательности. Однако довольно легко создать метод расширения, который позволит вам использовать лямбда-выражения с 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)));
}

Тогда вы можете использовать:

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

Обновляет существующий список так же, как это обычно делает List<T>.Sort.

1 голос
/ 07 ноября 2016

Преобразование List<T> в IEnumerable<T>

List<T> реализует IEnumerable<T> (и многие другие, такие как IList<T>, ICollection<T>), поэтому нет необходимости преобразовывать список обратно в IEnumerable, поскольку он уже IEnumerable<T>.

Пример:

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;

Вы также можете использовать Enumerable.AsEnumerable() метод

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

Преобразование IEnumerable<T> в List<T>

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

Это полезно в Entity Framework .

0 голосов
/ 28 августа 2014

Чтобы предотвратить дублирование в памяти, resharper предлагает следующее:

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

.ToList () возвращает новый неизменный список. Таким образом, изменения в listAgain не влияют на myList в ответе @Tamas Czinege. Это верно в большинстве случаев по крайней мере по двум причинам: это помогает предотвратить изменения в одной области, влияющие на другую область (слабая связь), и это очень читабельно, поскольку мы не должны разрабатывать код с проблемами компилятора.

Но есть определенные случаи, такие как работа в тесном цикле или работа во встроенной системе или системе с небольшим объемом памяти, где должны учитываться соображения компилятора.

...