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

Kiểm tra Hashtable bằng nhau trong C#

Giới thiệu

Để kiểm tra hai Hashtable có bằng nhau hay không, sử dụng phương thức Equals(). Tuy nhiên, Hashtable.Equals() kế thừa từ Object.Equals() so sánh tham chiếu (reference equality), không so sánh nội dung. Để so sánh nội dung, cần duyệt thủ công hoặc dùng LINQ.

Ví dụ 1: Hai Hashtable khác nhau

using System;
using System.Collections;

public class Demo {
    public static void Main() {
        Hashtable hash1 = new Hashtable();
        hash1.Add("1", "Kevin");
        hash1.Add("2", "Steve");
        hash1.Add("3", "Tim");
        hash1.Add("4", "Gary");
        hash1.Add("5", "Kevin");
        hash1.Add("6", "Steve");
        hash1.Add("7", "Tom");
        hash1.Add("8", "Stephen");

        Console.WriteLine("HashSet1...");
        ICollection keys = hash1.Keys;
        foreach (string k in keys) {
            Console.WriteLine(k + ": " + hash1[k]);
        }

        Hashtable hash2 = new Hashtable();
        hash2.Add("1", "Kevin");
        hash2.Add("2", "Steve");
        hash2.Add("3", "John");
        hash2.Add("4", "Tim");

        keys = hash2.Keys;
        Console.WriteLine("\nHashSet2...");
        foreach (string k in keys) {
            Console.WriteLine(k + ": " + hash2[k]);
        }

        Console.WriteLine("\nHai Hashtable bằng nhau (Equals)? " + hash1.Equals(hash2));
    }
}

Đầu ra ví dụ 1

HashSet1...
1: Kevin
2: Steve
3: Tim
4: Gary
5: Kevin
6: Steve
7: Tom
8: Stephen

HashSet2...
1: Kevin
2: Steve
3: John
4: Tim

Hai Hashtable bằng nhau (Equals)? False

Ví dụ 2: Hai Hashtable khác key và value

using System;
using System.Collections;

public class Demo {
    public static void Main() {
        Hashtable hash1 = new Hashtable();
        hash1.Add("1", "Kevin");
        hash1.Add("2", "Steve");
        hash1.Add("3", "John");
        hash1.Add("4", "Tim");

        Console.WriteLine("HashSet1...");
        ICollection keys = hash1.Keys;
        foreach (string k in keys) {
            Console.WriteLine(k + ": " + hash1[k]);
        }

        Hashtable hash2 = new Hashtable();
        hash2.Add("1", "Nathan");
        hash2.Add("2", "Gary");
        hash2.Add("3", "John");
        hash2.Add("4", "Tim");
        hash2.Add("5", "Steve");

        keys = hash2.Keys;
        Console.WriteLine("\nHashSet2...");
        foreach (string k in keys) {
            Console.WriteLine(k + ": " + hash2[k]);
        }

        Console.WriteLine("\nHai Hashtable bằng nhau (Equals)? " + hash1.Equals(hash2));
    }
}

Đầu ra ví dụ 2

HashSet1...
1: Kevin
2: Steve
3: John
4: Tim

HashSet2...
1: Nathan
2: Gary
3: John
4: Tim
5: Steve

Hai Hashtable bằng nhau (Equals)? False

Giải thích quan trọng

  • hash1.Equals(hash2) trả về true chỉ khi hash1 và hash2 tham chiếu đến cùng một đối tượng (reference equality).
  • Hashtable không override Equals() để so sánh nội dung.
  • Kết quả luôn false cho hai instance khác nhau, dù nội dung y hệt.

Cách so sánh nội dung Hashtable đúng cách

using System;
using System.Collections;
using System.Linq;

public static bool ContentEquals(Hashtable h1, Hashtable h2) {
    if (h1.Count != h2.Count) return false;
    
    foreach (DictionaryEntry entry in h1) {
        if (!h2.ContainsKey(entry.Key)) return false;
        if (!Equals(entry.Value, h2[entry.Key])) return false;
    }
    return true;
}

// Hoặc dùng LINQ (cần cast)
public static bool ContentEqualsLinq(Hashtable h1, Hashtable h2) {
    return h1.Count == h2.Count &&
           h1.Keys.Cast().All(k => h2.Contains(k) && Equals(h1[k], h2[k]));
}


So sánh Hashtable vs Dictionary<TKey, TValue>

Đặc điểmHashtableDictionary<TKey, TValue>
Equals()Reference equalityReference equality (cũng không so sánh nội dung)
Type safetyKhông (object)Có (generic)
Null keyCho phépKhông cho phép
Thread-safeCó SyncRoot wrapperKhông (dùng ConcurrentDictionary)
Hiệu năngThấp hơn (boxing)Cao hơn

Khuyến nghị

  • Luôn dùng Dictionary<TKey, TValue> thay vì Hashtable trong code mới.
  • Cần so sánh nội dung: tự viết method so sánh key-count và từng cặp key-value.
  • Dùng StructuralEqualityComparer (cho array/tuple) không áp dụng cho Hashtable.