Как преобразовать List<MyObject> в IEnumerable<MyObject>, а затем снова?
Я хочу сделать это, чтобы запустить ряд операторов LINQ в List, e. г. Sort()
Как преобразовать List<MyObject> в IEnumerable<MyObject>, а затем снова?
Я хочу сделать это, чтобы запустить ряд операторов LINQ в List, e. г. Sort()
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();
A List<T> является IEnumerable<T>, поэтому на самом деле нет необходимости "преобразовывать" a List<T> в IEnumerable<T>.
Так как a List<T> является IEnumerable<T>, вы можете просто назначить List<T> переменной типа IEnumerable<T>.
Другим способом, не каждый IEnumerable<T> является отключение List<T>, поэтому вам нужно будет вызвать метод члена ToList() для IEnumerable<T>.
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()
Кроме того: обратите внимание, что стандартные операторы LINQ (как в предыдущем примере) не меняют существующий список - list.OrderBy(...).ToList() создаст новый список на основе упорядоченной последовательности. Однако довольно просто создать метод расширения, который позволяет использовать lambdas с 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.
List<T> в IEnumerable<T> List<T> реализует IEnumerable<T> (и многие другие, такие как IList<T>, ICollection<T>), поэтому нет необходимости преобразовывать List обратно в 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.
Чтобы предотвратить дублирование в памяти, 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. В большинстве случаев это верно по крайней мере по двум причинам: это помогает предотвратить изменения в одной области, влияющие на другую область (свободная связь), и это очень читаемо, так как мы не должны разрабатывать код с проблемами компилятора.
Но есть определенные экземпляры, например, находящиеся в плотном цикле или работающие во встроенной или низкоуровневой системе, где следует учитывать соображения компилятора.