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

Phương thức Object.GetHashCode() trong C#

Giới thiệu

Phương thức ảo GetHashCode() của Object trả về mã băm (hash code) 32-bit signed integer cho đối tượng. Mặc định implementation dựa trên tham chiếu (reference equality) cho reference type, hoặc giá trị cho value type. Dùng cho hash-based collections: Dictionary, HashSet, Hashtable.

Cú pháp

public virtual int GetHashCode();

Ví dụ 1 - Object và String mặc định

using System;

public class Demo
{
    public static void Main()
    {
        Object ob = new Object();
        String str = "Jim";

        Type type1 = ob.GetType();
        Type type2 = str.GetType();

        Console.WriteLine("Hash Code của Type Object = " + type1.GetHashCode());
        Console.WriteLine("Hash Code của Type String = " + type2.GetHashCode());
    }
}

Kết quả

Hash Code của Type Object = 30015890
Hash Code của Type String = 21083178

Ví dụ 2 - Override GetHashCode cho struct

using System;

public struct Value
{
    private int v1;
    private int v2;
    private int v3;

    public Value(int v1, int v2, int v3)
    {
        this.v1 = v1;
        this.v2 = v2;
        this.v3 = v3;
    }

    public override int GetHashCode()
    {
        // Kết hợp hash code của các trường (cách phổ biến)
        return Tuple.Create(v1, v2, v3).GetHashCode();
        // Hoặc: return HashCode.Combine(v1, v2, v3); // .NET Core 2.1+
    }
}

public class Demo
{
    public static void Main()
    {
        Value v = new Value(1, 7, 12);
        Console.WriteLine(v.GetHashCode()); // 1258

        v = new Value(12, 8, 7);
        Console.WriteLine(v.GetHashCode()); // 12803

        v = new Value(8, 7, 12);
        Console.WriteLine(v.GetHashCode()); // 8931
    }
}

Kết quả

1258
12803
8931

Quy tắc quan trọng khi override GetHashCode()

  1. Consistency: Nếu Equals(a, b) == true thì a.GetHashCode() == b.GetHashCode() bắt buộc true.
  2. Stability: Hash code không đổi trong vòng đời object (trường hợp dùng trong hash table). Nên chỉ dùng các trường immutable (readonly).
  3. Distribution: Phân bố đều để giảm collision.
  4. Performance: Tính toán nhanh.

Cách combine hash code hiện đại (.NET Core 2.1+)

public override int GetHashCode()
{
    return HashCode.Combine(field1, field2, field3);
}

Lưu ý quan trọng

  • Không dùng GetHashCode() làm unique ID (có collision).
  • Không persist hash code (lưu DB, file) vì có thể khác giữa phiên bản/runtime/architecture.
  • Struct mặc định có GetHashCode() dựa trên trường đầu tiên non-null (có thể gây collision cao).
  • Record types (C# 9+) tự động generate Equals/GetHashCode dựa trên properties.