Câu trả lời:
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();
using System.Linq;
nếu không bạn sẽ không thể Ghi danh ()
A List<T>
là một IEnumerable<T>
, vì vậy thực tế, không cần phải 'chuyển đổi' a List<T>
thành an IEnumerable<T>
. Vì a List<T>
là một IEnumerable<T>
, bạn có thể chỉ cần gán List<T>
một biến kiểu IEnumerable<T>
.
Ngược lại, không phải mọi thứ đều IEnumerable<T>
là một diễn đàn List<T>
, vì vậy bạn sẽ phải gọi ToList()
phương thức thành viên của IEnumerable<T>
.
A List<T>
đã là an IEnumerable<T>
, vì vậy bạn có thể chạy các câu lệnh LINQ trực tiếp trên List<T>
biến của mình .
Nếu bạn không thấy các phương thức mở rộng LINQ như OrderBy()
tôi đoán thì đó là do bạn không có lệnh using System.Linq
trong tệp nguồn của mình.
Tuy nhiên, bạn cần chuyển đổi kết quả biểu thức LINQ trở lại một List<T>
cách rõ ràng:
List<Customer> list = ...
list = list.OrderBy(customer => customer.Name).ToList()
Ngoài ra: Lưu ý rằng các toán tử LINQ chuẩn (như ví dụ trước đó) không thay đổi danh sách hiện có - list.OrderBy(...).ToList()
sẽ tạo một danh sách mới dựa trên trình tự được sắp xếp lại. Tuy nhiên, khá dễ dàng để tạo một phương thức mở rộng cho phép bạn sử dụng lambdas với 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)));
}
Sau đó, bạn có thể sử dụng:
list.Sort(x=>x.SomeProp); // etc
Điều này cập nhật danh sách hiện có theo cùng một cách List<T>.Sort
thường làm.
ToList
- Tuy nhiên, tôi sẽ làm rõ.
List<T>
sangIEnumerable<T>
List<T>
triển khai IEnumerable<T>
(và nhiều thứ khác chẳng hạn IList<T>, ICollection<T>
) do đó không cần phải chuyển đổi một Danh sách trở lại IEnumerable vì nó đã là một IEnumerable<T>
.
Thí dụ:
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;
Bạn cũng có thể sử dụng Enumerable.AsEnumerable()
phương pháp
IEnumerable<Person> iPersonList = people.AsEnumerable();
IEnumerable<T>
sangList<T>
IEnumerable<Person> OriginallyIEnumerable = new List<Person>() { person1, person2 };
List<Person> convertToList = OriginallyIEnumerable.ToList();
Điều này rất hữu ích trong Entity Framework .
Để ngăn trùng lặp trong bộ nhớ, trình sạc lại đang đề xuất điều này:
List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myList as List<string>() ?? myEnumerable.ToList();
.ToList () trả về một danh sách bất biến mới. Vì vậy, các thay đổi đối với listAgain không ảnh hưởng đến myList trong câu trả lời @Tamas Czinege. Điều này đúng trong hầu hết các trường hợp vì ít nhất hai lý do: Điều này giúp ngăn chặn các thay đổi trong một khu vực ảnh hưởng đến khu vực khác (khớp nối lỏng lẻo) và nó rất dễ đọc, vì chúng ta không nên thiết kế mã với mối quan tâm của trình biên dịch.
Nhưng có một số trường hợp nhất định, chẳng hạn như ở trong một vòng lặp chặt chẽ hoặc làm việc trên một hệ thống nhúng hoặc bộ nhớ thấp, trong đó cần cân nhắc trình biên dịch.