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

การดึงช่วงข้อมูลจาก List ใน C# ด้วย GetRange()

เมธอด GetRange(int index, int count) ของ List<T> ใช้ดึงสับลิสต์ (Sublist) จากตำแหน่งที่กำหนด จำนวนตามที่ระบุ คืนค่า List<T> ใหม่ (Shallow Copy) ไม่ส่งผลต่อลิสต์เดิม

รูปแบบการใช้งาน

List source = new List { 10, 20, 30, 40, 50 };
List subset = source.GetRange(1, 3); // เริ่มดัชนี 1 จำนวน 3 รายการ → { 20, 30, 40 }

โค้ดตัวอย่างสมบูรณ์

using System;
using System.Collections.Generic;

public class Demo
{
    public static void Main()
    {
        List numbers = new List { 10, 20, 30, 40, 50 };
        
        Console.WriteLine("ลิสต์ต้นฉบับ:");
        Console.WriteLine(string.Join(", ", numbers));
        
        // ดึงช่วงดัชนี 1 ถึง 3 (3 รายการ)
        List range = numbers.GetRange(1, 3);
        Console.WriteLine($"\nGetRange(1, 3): {string.Join(", ", range)}"); // 20, 30, 40
        
        // ดึง 2 รายการสุดท้าย
        List lastTwo = numbers.GetRange(numbers.Count - 2, 2);
        Console.WriteLine($"2 รายการสุดท้าย: {string.Join(", ", lastTwo)}"); // 40, 50
        
        // ดึงตั้งแต่กลางไปจนจบ
        List fromMiddle = numbers.GetRange(2, numbers.Count - 2);
        Console.WriteLine($"จากกลางไปจนจบ: {string.Join(", ", fromMiddle)}"); // 30, 40, 50
        
        // แสดงว่าเป็น Shallow Copy (Reference Type จะชี้ Object เดียวกัน)
        Console.WriteLine("\n--- Shallow Copy Demo (Reference Type) ---");
        List builders = new List
        {
            new StringBuilder("A"),
            new StringBuilder("B"),
            new StringBuilder("C")
        };
        
        List sub = builders.GetRange(0, 2);
        sub[0].Append(" Modified");
        
        Console.WriteLine($"ต้นฉบับ[0]: {builders[0]}"); // A Modified (Object เดียวกัน!)
        Console.WriteLine($"สับลิสต์[0]: {sub[0]}");     // A Modified
    }
}

ผลลัพธ์

ลิสต์ต้นฉบับ:
10, 20, 30, 40, 50

GetRange(1, 3): 20, 30, 40
2 รายการสุดท้าย: 40, 50
จากกลางไปจนจบ: 30, 40, 50

--- Shallow Copy Demo (Reference Type) ---
ต้นฉบับ[0]: A Modified
สับลิสต์[0]: A Modified

GetRange vs LINQ Skip/Take

ลักษณะGetRange(index, count)Skip/Take (LINQ)
คืนค่าList<T> (Concrete)IEnumerable<T> (Deferred)
ประสิทธิภาพO(count) - Copy โดยตรงO(n) - Iterator
Random Accessได้ (List)ไม่ได้ (ต้อง ToList())
Bounds Checkingโยน ArgumentExceptionปลอดภัย (คืน Empty)
Reference/Value TypeShallow Copy ทั้งคู่Shallow Copy ทั้งคู่

ข้อยกเว้นที่อาจเกิดขึ้น

List list = new List { 1, 2, 3 };

// ArgumentOutOfRangeException
list.GetRange(-1, 2);  // Index ติดลบ
list.GetRange(0, 5);   // Count มากเกินไป
list.GetRange(2, 2);   // Index + Count > List.Count

การใช้งานจริง: Pagination (แบ่งหน้า)

public class PagedList
{
    private readonly List _source;
    private readonly int _pageSize;
    
    public PagedList(List source, int pageSize)
    {
        _source = source;
        _pageSize = pageSize;
    }
    
    public List GetPage(int pageNumber) // 1-based
    {
        if (pageNumber < 1) throw new ArgumentOutOfRangeException(nameof(pageNumber));
        
        int skip = (pageNumber - 1) * _pageSize;
        if (skip >= _source.Count) return new List();
        
        int take = Math.Min(_pageSize, _source.Count - skip);
        return _source.GetRange(skip, take);
    }
    
    public int TotalPages => (_source.Count + _pageSize - 1) / _pageSize;
}

// ใช้งาน
var allItems = Enumerable.Range(1, 100).ToList();
var paged = new PagedList(allItems, 10);

for (int page = 1; page <= paged.TotalPages; page++)
{
    var pageItems = paged.GetPage(page);
    Console.WriteLine($"Page {page}: {string.Join(", ", pageItems)}");
}

ข้อควรระวัง

  • พารามิเตอร์: index (0-based), count (จำนวนรายการ) - ทั้งคู่ต้อง ≥ 0
  • index + count ต้อง ≤ Count มิฉะนั้นโยน ArgumentException
  • คืน Shallow Copy - Reference Type จะชี้ Object เดียวกัน
  • หากต้องการ Deep Copy ต้อง Clone Object เอง
  • ไม่มีเมธอด SetRange - ต้องใช้ InsertRange หรือลูปแทน