เมธอด 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
| วิธี | Type | Immutable? | 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/FrozenDictionary | Struct (True Immutable) | ไม่ (Snapshot) | เร็วที่สุด Read | .NET 8+ |
| Array (T[]) | Array | ขนาดคงที่ แต่ Element เปลี่ยนได้ | ไม่ (Copy) | All |