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

สร้าง Wrapper แบบ Read-Only สำหรับ ArrayList ใน C#

เมธอด Static ArrayList.ReadOnly(ArrayList list) สร้าง Wrapper แบบอ่านอย่างเดียว (Read-Only Wrapper) ที่ป้องกันการแก้ไขข้อมูลได้ แต่ข้อมูลต้นฉบับยังแก้ไขได้ (Live View)

ตัวอย่างที่ 1: ArrayList ปกติ (ไม่ใช่ Read-Only)

using System;
using System.Collections;

public class Demo
{
    public static void Main()
    {
        ArrayList list = new ArrayList();
        list.Add("One");
        list.Add("Two");
        list.Add("Three");
        list.Add("Four");
        list.Add("Five");
        list.Add("Six");
        list.Add("Seven");
        list.Add("Eight");

        Console.WriteLine("ArrayList องค์ประกอบ...");
        foreach (string str in list)
        {
            Console.WriteLine(str);
        }

        Console.WriteLine("ArrayList เป็น Read-Only? = " + list.IsReadOnly); // False
    }
}

ผลลัพธ์

ArrayList องค์ประกอบ...
One
Two
Three
Four
Five
Six
Seven
Eight
ArrayList เป็น Read-Only? = False

ตัวอย่างที่ 2: สร้าง Read-Only Wrapper

using System;
using System.Collections;

public class Demo
{
    public static void Main()
    {
        ArrayList list = new ArrayList();
        list.Add("One");
        list.Add("Two");
        list.Add("Three");
        list.Add("Four");
        list.Add("Five");
        list.Add("Six");
        list.Add("Seven");
        list.Add("Eight");

        Console.WriteLine("ArrayList องค์ประกอบ...");
        foreach (string str in list)
        {
            Console.WriteLine(str);
        }

        Console.WriteLine("ArrayList เป็น Read-Only? = " + list.IsReadOnly); // False

        // สร้าง Read-Only Wrapper
        ArrayList list2 = ArrayList.ReadOnly(list);

        Console.WriteLine("ArrayList เป็น Read-Only ตอนนี้? = " + list2.IsReadOnly); // True

        // ลองเพิ่มใน Wrapper -> จะโยน NotSupportedException
        try
        {
            list2.Add("Nine");
        }
        catch (NotSupportedException ex)
        {
            Console.WriteLine("Error: " + ex.Message); // Collection is read-only.
        }

        // แต่ต้นฉบับยังแก้ไขได้
        list.Add("Nine"); // OK
        Console.WriteLine("เพิ่มในต้นฉบับสำเร็จ จำนวน = " + list.Count); // 9
        Console.WriteLine("Wrapper มองเห็น Nine? = " + list2.Contains("Nine")); // True (Live View)
    }
}

ผลลัพธ์

ArrayList องค์ประกอบ...
One
Two
Three
Four
Five
Six
Seven
Eight
ArrayList เป็น Read-Only? = False
ArrayList เป็น Read-Only ตอนนี้? = True
Error: Collection is read-only.
เพิ่มในต้นฉบับสำเร็จ จำนวน = 9
Wrapper มองเห็น Nine? = True

ข้อสังเกตสำคัญ

  • ArrayList.ReadOnly(list) คืนค่า Wrapper (ไม่ใช่สำเนา) - เป็น Live View ของต้นฉบับ
  • Wrapper มี IsReadOnly = true และโยน NotSupportedException เมื่อพยายามแก้ไข
  • การเปลี่ยนแปลงต้นฉบับจะสะท้อนใน Wrapper ทันที
  • ArrayList เป็น Non-generic Legacy Class แนะนำใช้ List<T> แทน

ทางเลือกสมัยใหม่สำหรับ List<T> (Generic)

// 1. IReadOnlyList<T> (Interface - .NET 4.5+)
List<string> list = new List<string> { "One", "Two" };
IReadOnlyList<string> readOnly = list; // Implicit Cast

// 2. ReadOnlyCollection<T> (Wrapper Class)
var readOnlyColl = new ReadOnlyCollection<string>(list);
// หรือ list.AsReadOnly() (Extension Method ใน List<T>)

// 3. FrozenSet / FrozenDictionary (.NET 8+ - True Immutable)
using System.Collections.Frozen;
var frozen = list.ToFrozenSet(); // Immutable, High Performance Lookup

// 4. Array (Immutable by Nature)
string[] array = list.ToArray(); // Copy เป็น Array (Fixed Size, Immutable Elements)

เปรียบเทียบ Read-Only Approaches

วิธีTypeImmutable?Live View?Version
ArrayList.ReadOnly()Wrapper (Non-Generic)ไม่ (Wrapper)ใช่.NET Framework
List<T>.AsReadOnly()ReadOnlyCollection<T>ไม่ (Wrapper)ใช่.NET 2.0+
IReadOnlyList<T>Interfaceขึ้นกับ Implementationใช่.NET 4.5+
FrozenSet/FrozenDictionaryStruct (True Immutable)ไม่ (Snapshot)เร็วที่สุด Read.NET 8+
Array (T[])Arrayขนาดคงที่ แต่ Element เปลี่ยนได้ไม่ (Copy)All