Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Tạo wrapper chỉ đọc cho ArrayList trong C#

Phương thức tĩnh ArrayList.ReadOnly() trả về một wrapper chỉ đọc (read-only wrapper) bao bọc ArrayList gốc. Wrapper này ngăn chặn việc thêm, xóa, sửa phần tử nhưng vẫn cho phép đọc dữ liệu.

Ví dụ 1: ArrayList bình thường

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("Các phần tử của ArrayList...");
        foreach (string str in list)
        {
            Console.WriteLine(str);
        }

        Console.WriteLine("ArrayList chỉ đọc? = " + list.IsReadOnly);
    }
}

Kết quả

Các phần tử của ArrayList...
One
Two
Three
Four
Five
Six
Seven
Eight
ArrayList chỉ đọc? = False

Ví dụ 2: Tạo wrapper chỉ đọc

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("Các phần tử của ArrayList...");
        foreach (string str in list)
        {
            Console.WriteLine(str);
        }

        Console.WriteLine("ArrayList chỉ đọc? = " + list.IsReadOnly);

        // Tạo wrapper chỉ đọc
        ArrayList list2 = ArrayList.ReadOnly(list);

        Console.WriteLine("ArrayList chỉ đọc bây giờ? = " + list2.IsReadOnly);

        // Thử sửa - ném NotSupportedException
        try
        {
            list2.Add("Nine");
        }
        catch (NotSupportedException ex)
        {
            Console.WriteLine("Lỗi khi Add: " + ex.Message);
        }

        try
        {
            list2[0] = "Zero";
        }
        catch (NotSupportedException ex)
        {
            Console.WriteLine("Lỗi khi gán index: " + ex.Message);
        }
    }
}

Kết quả

Các phần tử của ArrayList...
One
Two
Three
Four
Five
Six
Seven
Eight
ArrayList chỉ đọc? = False
ArrayList chỉ đọc bây giờ? = True
Lỗi khi Add: Collection is read-only.
Lỗi khi gán index: Collection is read-only.

Đặc điểm của ArrayList.ReadOnly()

Đặc điểm Mô tả
Trả về ArrayList (wrapper)
IsReadOnly true
IsFixedSize true
Dữ liệu gốc Chia sẻ (shallow wrapper)
Thay đổi gốc Ảnh hưởng đến wrapper

Lưu ý quan trọng: Shallow Wrapper

⚠️ Quan trọng: ArrayList.ReadOnly() tạo một wrapper nông, không phải bản sao. Thay đổi trên ArrayList gốc SẼ phản ánh lên wrapper chỉ đọc.
ArrayList original = new ArrayList { "A", "B", "C" };
ArrayList readOnly = ArrayList.ReadOnly(original);

Console.WriteLine(readOnly[0]); // "A"

// Thay đổi original
original[0] = "Z";

Console.WriteLine(readOnly[0]); // "Z" - THAY ĐỔI ĐƯỢC PHẢN ÁNH!

Tạo bản sao độc lập (Deep Copy)

// Cách 1: Constructor
ArrayList copy = new ArrayList(original);

// Cách 2: AddRange
ArrayList copy2 = new ArrayList();
copy2.AddRange(original);

// Cách 3: ToArray() -> List
ArrayList copy3 = new ArrayList(original.ToArray());

// Bây giờ copy.IsReadOnly = false, độc lập hoàn toàn

So sánh với List<T> hiện đại

Đặc điểm ArrayList.ReadOnly() List<T> + ReadOnlyCollection<T>
Type-safe Không (object) Có (Generic)
Interface IList (non-generic) IReadOnlyList<T> / IReadOnlyCollection<T>
Wrapper behavior Shallow Shallow
// Cách hiện đại khuyến nghị
List<string> list = new List<string> { "One", "Two", "Three" };
var readOnly = new System.Collections.ObjectModel.ReadOnlyCollection<string>(list);

Console.WriteLine(readOnly.IsReadOnly); // True
// readOnly.Add("Four"); // Compile error - không có phương thức Add

Lưu ý

  • ArrayList đã lỗi thời - khuyến nghị dùng List<T>
  • Wrapper chỉ đọc ném NotSupportedException cho: Add, Remove, Clear, Insert, RemoveAt, Indexer set
  • Vẫn cho phép: Count, Indexer get, Contains, IndexOf, CopyTo, GetEnumerator
  • Namespace: System.Collections