IEnumerable<T> คือ Interface พื้นฐานสำหรับ Sequence ที่วนรอบได้ (Forward-only) ในขณะที่ List<T> เป็น Concrete Collection ที่เข้าถึงด้วย Index ได้ รองรับ Add/Remove/Sort
การแปลง IEnumerable → List
1. List Constructor (แนะนำ - ชัดเจนที่สุด)
IEnumerable<int> numbers = Enumerable.Range(1, 5); // 1,2,3,4,5
List<int> list = new List<int>(numbers); // Copy ทุก Element เข้า List
2. ToList() Extension Method ( LINQ - สั้นที่สุด)
List<int> list = numbers.ToList(); // ต้อง using System.Linq
3. เพิ่มทีละตัวด้วย Loop (Manual)
var list = new List<int>();
foreach (var item in numbers) list.Add(item);
การแปลง List → IEnumerable
1. Implicit Conversion (List Implement IEnumerable)
List<int> list = new List<int> { 1, 2, 3 };
IEnumerable<int> enumerable = list; // Implicit Upcast - Zero Cost
2. AsEnumerable() (Explicit - LINQ)
IEnumerable<int> enumerable = list.AsEnumerable(); // คืน IEnumerable Wrapper
3. Cast<T>() / OfType<T>() (สำหรับ Non-generic / Polymorphism)
ArrayList oldList = new ArrayList { 1, 2, 3 };
IEnumerable<int> enumerable = oldList.Cast<int>(); // Non-generic → Generic
ตัวอย่างครบถ้วน
using System;
using System.Collections.Generic;
using System.Linq;
static void Main()
{
// 1. IEnumerable → List
IEnumerable<int> seq = Enumerable.Range(1, 5);
List<int> list1 = new List<int>(seq); // Constructor
List<int> list2 = seq.ToList(); // LINQ
Console.WriteLine("List from IEnumerable:");
list1.ForEach(Console.WriteLine);
// 2. List → IEnumerable
List<int> sourceList = new List<int> { 10, 20, 30 };
IEnumerable<int> seq1 = sourceList; // Implicit
IEnumerable<int> seq2 = sourceList.AsEnumerable(); // Explicit
Console.WriteLine("\nIEnumerable from List:");
foreach (var item in seq1) Console.WriteLine(item);
// 3. Round-trip
var roundTrip = list1.AsEnumerable().ToList();
Console.WriteLine($"\nRound-trip Count: {roundTrip.Count}"); // 5
}
ผลลัพธ์
List from IEnumerable:
1
2
3
4
5
IEnumerable from List:
10
20
30
Round-trip Count: 5
ประสิทธิภาพและความหมาย
| Method | Allocation | Execution | ใช้เมื่อไหร่ |
|---|---|---|---|
new List(enumerable) |
New List + Copy | Eager (Immediate) | ต้องการ List จริง ต้องการ Random Access |
.ToList() |
New List + Copy | Eager | LINQ Pipeline ตอนท้าย |
| Implicit Cast | None (Reference) | Lazy (Deferred) | แค่ต้องการ IEnumerable View |
.AsEnumerable() |
Wrapper Object | Lazy | ซ่อน List Methods (Force IEnumerable) |
ข้อสังเกต
IEnumerableเป็น Read-only Forward-only SequenceListเป็น Random Access, Mutable, ImplementsIEnumerable,ICollection,IList- การ Cast List → IEnumerable ไม่ Copy ข้อมูล (Reference เท่านั้น)
- หลีกเลี่ยง
.ToList()ซ้ำๆ ใน Pipeline (Performance)