IEnumerable<T> là interface cơ sở cho các collection chỉ đọc, duyệt tiến (forward-only). List<T> là collection cụ thể, truy cập bằng index, hỗ trợ thêm/xóa/sắp xếp.
IEnumerable -> List
// Cách 1: Constructor (khuyến nghị)
IEnumerable<int> numbers = Enumerable.Range(1, 5);
List<int> list1 = new List<int>(numbers);
// Cách 2: ToList() extension method
List<int> list2 = numbers.ToList();
// Cách 3: AddRange (nếu list đã tồn tại)
var list3 = new List<int>();
list3.AddRange(numbers);
List -> IEnumerable
List<int> list = new List<int> { 1, 2, 3, 4, 5 };
// Cách 1: Implicit conversion (List implements IEnumerable)
IEnumerable<int> enumerable1 = list;
// Cách 2: AsEnumerable() (explicit, trả về IEnumerable interface)
IEnumerable<int> enumerable2 = list.AsEnumerable();
// Cách 3: Cast (nếu cần upcast)
IEnumerable<object> enumerable3 = list.Cast<object>();
Ví dụ hoàn chỉnh
class Program
{
static void Main()
{
// IEnumerable -> List
IEnumerable<int> source = Enumerable.Range(1, 5);
List<int> list = source.ToList();
Console.WriteLine("List:");
foreach (var item in list) Console.Write($"{item} "); // 1 2 3 4 5
// List -> IEnumerable
IEnumerable<int> back = list.AsEnumerable();
Console.WriteLine("\nBack to IEnumerable:");
foreach (var item in back) Console.Write($"{item} "); // 1 2 3 4 5
Console.ReadLine();
}
}
So sánh đặc điểm
| Đặc điểm | IEnumerable<T> | List<T> |
|---|---|---|
| Truy cập index | Không | Có (O(1)) |
| Thêm/Xóa | Không | Có |
| Đếm Count | O(n) (duyệt) | O(1) (property) |
| LINQ | Deferred execution | Immediate nếu dùng ToList() |
| Memory | Lazy (streaming) | Eager (toàn bộ trong RAM) |
Khi nào dùng cái nào?
- IEnumerable<T>: Trả về từ method, parameter input, LINQ query, streaming data lớn.
- List<T>: Cần truy cập index, thêm/xóa, duyệt nhiều lần, biết size trước.
- IReadOnlyList<T>: Trả về cho caller chỉ đọc, có Count + indexer.
Lưu ý: ToList() thực thi query LINQ ngay lập tức (eager). Nếu chỉ duyệt một lần, giữ IEnumerable để tận dụng deferred execution.