Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

วิธีแปลง IEnumerable เป็น List และ List กลับเป็น IEnumerable ใน C#

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 Sequence
  • List เป็น Random Access, Mutable, Implements IEnumerable, ICollection, IList
  • การ Cast List → IEnumerable ไม่ Copy ข้อมูล (Reference เท่านั้น)
  • หลีกเลี่ยง .ToList() ซ้ำๆ ใน Pipeline (Performance)