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

สร้างสำเนา Read-Only ของ OrderedDictionary ใน C#

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

ตัวอย่างที่ 1: สร้าง Read-Only Copy และตรวจสอบ

using System;
using System.Collections;
using System.Collections.Specialized;

public class Demo
{
    public static void Main()
    {
        OrderedDictionary dict1 = new OrderedDictionary();
        dict1.Add("A", "Books");
        dict1.Add("B", "Electronics");
        dict1.Add("C", "Smart Wearables");
        dict1.Add("D", "Pet Supplies");
        dict1.Add("E", "Clothing");
        dict1.Add("F", "Footwear");

        Console.WriteLine("OrderedDictionary1 องค์ประกอบ...");
        foreach (DictionaryEntry d in dict1)
        {
            Console.WriteLine(d.Key + " " + d.Value);
        }

        OrderedDictionary dict2 = new OrderedDictionary();
        dict2.Add("1", "One");
        dict2.Add("2", "Two");
        dict2.Add("3", "Three");
        dict2.Add("4", "Four");
        dict2.Add("5", "Five");
        dict2.Add("6", "Six");

        Console.WriteLine("\nOrderedDictionary2 องค์ประกอบ...");
        foreach (DictionaryEntry d in dict2)
        {
            Console.WriteLine(d.Key + " " + d.Value);
        }

        Console.WriteLine("\nOrderedDictionary1 เท่ากับ OrderedDictionary2? = " + (dict1.Equals(dict2)));

        // สร้าง Read-Only Wrapper จาก dict2
        OrderedDictionary orderedDict = dict2.AsReadOnly();

        Console.WriteLine("OrderedDictionary เป็น Read-Only? = " + orderedDict.IsReadOnly); // True
    }
}

ผลลัพธ์

OrderedDictionary1 องค์ประกอบ...
A Books
B Electronics
C Smart Wearables
D Pet Supplies
E Clothing
F Footwear
OrderedDictionary2 องค์ประกอบ...
1 One
2 Two
3 Three
Four
5 Five
6 Six
OrderedDictionary1 เท่ากับ OrderedDictionary2? = False
OrderedDictionary เป็น Read-Only? = True

ตัวอย่างที่ 2: สร้าง Read-Only จาก Dictionary เดียว

using System;
using System.Collections;
using System.Collections.Specialized;

public class Demo
{
    public static void Main()
    {
        OrderedDictionary dict = new OrderedDictionary();
        dict.Add("A", "Books");
        dict.Add("B", "Electronics");
        dict.Add("C", "Smart Wearables");
        dict.Add("D", "Pet Supplies");
        dict.Add("E", "Clothing");
        dict.Add("F", "Footwear");

        Console.WriteLine("OrderedDictionary องค์ประกอบ...");
        foreach (DictionaryEntry d in dict)
        {
            Console.WriteLine(d.Key + " " + d.Value);
        }

        // สร้าง Read-Only Wrapper
        OrderedDictionary orderedDict = dict.AsReadOnly();

        Console.WriteLine("OrderedDictionary เป็น Read-Only? = " + orderedDict.IsReadOnly); // True

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

        // แต่ข้อมูลต้นฉบับยังแก้ไขได้
        dict.Add("G", "Test"); // OK
        Console.WriteLine("เพิ่มในต้นฉบับสำเร็จ จำนวน = " + dict.Count); // 7
        Console.WriteLine("Read-Only Wrapper มองเห็น G? = " + orderedDict.Contains("G")); // True (Live View)
    }
}

ผลลัพธ์

OrderedDictionary องค์ประกอบ...
A Books
B Electronics
C Smart Wearables
D Pet Supplies
E Clothing
F Footwear
OrderedDictionary เป็น Read-Only? = True
Error: Collection is read-only.
เพิ่มในต้นฉบับสำเร็จ จำนวน = 7
Read-Only Wrapper มองเห็น G? = True

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

  • AsReadOnly() คืนค่า Wrapper (ไม่ใช่สำเนา) - มองเห็นการเปลี่ยนแปลงของต้นฉบับ (Live View)
  • Wrapper จะโยน NotSupportedException เมื่อพยายาม Add, Remove, Clear, หรือแก้ไข
  • คุณสมบัติ IsReadOnly ของ Wrapper จะเป็น true
  • OrderedDictionary เป็น Non-generic (Legacy) ใช้ object key/value

ทางเลือกสมัยใหม่ (แนะนำ)

// 1. IReadOnlyDictionary<TKey, TValue> (Interface - .NET Core / .NET 5+)
var dict = new Dictionary<string, string> { { "A", "Books" } };
IReadOnlyDictionary<string, string> readOnly = dict; // Implicit cast

// 2. FrozenDictionary (Immutable, High Performance - .NET 8+)
using System.Collections.Frozen;
var frozen = new Dictionary<string, string> { { "A", "Books" } }.ToFrozenDictionary();
// frozen ไม่สามารถแก้ไขได้เลย (True Immutable) และ Lookup เร็วมาก

// 3. ReadOnlyDictionary<TKey, TValue> (Wrapper แบบ Generic)
var readOnlyDict = new ReadOnlyDictionary<string, string>(new Dictionary<string, string> { { "A", "Books" } });

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

วิธีImmutable?Live View?PerformanceVersion
AsReadOnly() (OrderedDictionary)ไม่ (Wrapper)ใช่ปานกลาง.NET Framework
ReadOnlyDictionary<TKey,TValue>ไม่ (Wrapper)ใช่ดี.NET 4.5+
IReadOnlyDictionary<TKey,TValue>ขึ้นกับ Implementationใช่ดี.NET Core
FrozenDictionary<TKey,TValue>ใช่ (True Immutable)ไม่ (Snapshot)ดีที่สุดสำหรับ Read.NET 8+