0Pricing
C# Academy · Pelajaran

Mengganti GetHashCode

Jaga konsistensi antara kesetaraan dan hashing.

Mengganti GetHashCode adalah pelajaran C# Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar C# Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus C# Academy mencakup 4 pelajaran total.

Mengapa GetHashCode Penting

Koleksi berbasis hash seperti Dictionary dan HashSet menggunakan GetHashCode untuk menempatkan item ke dalam keranjang. Jika Anda menimpa Equals tetapi tidak menimpa GetHashCode, koleksi ini dapat gagal menemukan item yang sama.

Aturan Emas

Kontraknya sederhana: jika dua objek sama, keduanya harus mengembalikan kode hash yang sama. Kebalikannya tidak diwajibkan; objek yang berbeda dapat memiliki kode hash yang sama, yang disebut tabrakan.

using System;

public struct Point
{
    public int X, Y;
    public Point(int x, int y) { X = x; Y = y; }
    public override bool Equals(object obj) => obj is Point p && p.X == X && p.Y == Y;
    public override int GetHashCode() => HashCode.Combine(X, Y);
}

public class Program
{
    public static void Main()
    {
        var a = new Point(1, 2);
        var b = new Point(1, 2);
        Console.WriteLine(a.Equals(b));
        Console.WriteLine(a.GetHashCode() == b.GetHashCode());
    }
}

Gunakan HashCode.Combine

Pembantu HashCode.Combine mencampurkan beberapa nilai bidang menjadi hash yang tersebar dengan baik. Inilah cara modern yang direkomendasikan untuk menerapkan GetHashCode.

using System;

public struct Color
{
    public int R, G, B;
    public Color(int r, int g, int b) { R = r; G = g; B = b; }
    public override bool Equals(object obj) => obj is Color c && c.R == R && c.G == G && c.B == B;
    public override int GetHashCode() => HashCode.Combine(R, G, B);
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new Color(255, 0, 0).GetHashCode() == new Color(255, 0, 0).GetHashCode());
    }
}

Tangani Kesamaan dan Pembuatan Hash Bersamaan

Selalu timpa Equals dan GetHashCode sebagai pasangan, dengan menggunakan bidang yang sama pada keduanya. Menggunakan bidang yang berbeda membuat objek yang sama menghasilkan hash yang berbeda.

using System;

public class Book
{
    public string Title;
    public int Year;
    public Book(string title, int year) { Title = title; Year = year; }
    public override bool Equals(object obj)
        => obj is Book b && b.Title == Title && b.Year == Year;
    public override int GetHashCode() => HashCode.Combine(Title, Year);
}

public class Program
{
    public static void Main()
    {
        var a = new Book("C#", 2020);
        var b = new Book("C#", 2020);
        Console.WriteLine(a.GetHashCode() == b.GetHashCode());
    }
}

Mengapa Kamus Membutuhkannya

Dictionary terlebih dahulu membuat hash kunci untuk menemukan keranjang, kemudian menggunakan Equals di dalam keranjang tersebut. Hash yang salah mengarahkan pencarian ke keranjang yang keliru sehingga kunci tidak pernah ditemukan.

using System;
using System.Collections.Generic;

public struct Coord
{
    public int X, Y;
    public Coord(int x, int y) { X = x; Y = y; }
    public override bool Equals(object obj) => obj is Coord c && c.X == X && c.Y == Y;
    public override int GetHashCode() => HashCode.Combine(X, Y);
}

public class Program
{
    public static void Main()
    {
        var map = new Dictionary<Coord, string> { [new Coord(2, 3)] = "hit" };
        Console.WriteLine(map[new Coord(2, 3)]);
    }
}

Membuat Hash dari Bidang yang Tidak Dapat Diubah

Kode hash harus stabil untuk suatu objek selama objek tersebut berada dalam koleksi hash. Dasarkan hash pada bidang yang tidak dapat diubah; jika kunci berubah setelah dimasukkan, koleksi dapat kehilangan jejaknya.

using System;

public class Account
{
    public readonly int Id; // immutable, safe to hash
    public string Nickname; // mutable, do not hash
    public Account(int id, string nick) { Id = id; Nickname = nick; }
    public override bool Equals(object obj) => obj is Account a && a.Id == Id;
    public override int GetHashCode() => Id.GetHashCode();
}

public class Program
{
    public static void Main()
    {
        var acc = new Account(42, "old");
        int h1 = acc.GetHashCode();
        acc.Nickname = "new"; // does not change the hash
        Console.WriteLine(h1 == acc.GetHashCode());
    }
}

Menangani Bidang Null

Jika suatu bidang dapat bernilai null, HashCode.Combine menanganinya dengan aman. Jika menghitungnya secara manual, tangani null untuk menghindari NullReferenceException.

using System;

public class Tag
{
    public string Name;
    public Tag(string name) { Name = name; }
    public override bool Equals(object obj) => obj is Tag t && t.Name == Name;
    public override int GetHashCode() => HashCode.Combine(Name); // null-safe
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new Tag(null).GetHashCode() == new Tag(null).GetHashCode());
    }
}

Tabrakan Itu Wajar

Kode hash berukuran 32 bit, sehingga tabrakan tidak dapat dihindari untuk kumpulan data besar. Hash yang baik hanya perlu menyebarkan nilai agar tabrakan jarang terjadi; Equals menyelesaikan tabrakan yang muncul.

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var set = new HashSet<int>();
        for (int i = 0; i < 5; i++) set.Add(i);
        // Equality still works perfectly even though hashing is imperfect in general
        Console.WriteLine(set.Contains(3));
        Console.WriteLine(set.Contains(99));
    }
}

Record Membuatnya untuk Anda

record secara otomatis membuat GetHashCode yang benar dari propertinya, sesuai dengan Equals berbasis nilainya. Ini adalah cara termudah untuk mendapatkan pembuatan hash yang benar.

using System;
using System.Collections.Generic;

public record Coord(int X, int Y);

public class Program
{
    public static void Main()
    {
        var set = new HashSet<Coord> { new Coord(1, 1) };
        Console.WriteLine(set.Contains(new Coord(1, 1)));
    }
}

Tipe Kesamaan yang Benar

Jika digabungkan: gunakan bidang yang sama dalam Equals dan GetHashCode, kunci yang tidak dapat diubah, serta HashCode.Combine untuk mencampurkan nilai. Tipe ini bekerja sempurna sebagai kunci kamus.

using System;
using System.Collections.Generic;

public struct ProductKey
{
    public string Sku;
    public int Variant;
    public ProductKey(string sku, int variant) { Sku = sku; Variant = variant; }
    public override bool Equals(object obj)
        => obj is ProductKey k && k.Sku == Sku && k.Variant == Variant;
    public override int GetHashCode() => HashCode.Combine(Sku, Variant);
}

public class Program
{
    public static void Main()
    {
        var stock = new Dictionary<ProductKey, int>
        {
            [new ProductKey("ABC", 1)] = 10
        };
        Console.WriteLine(stock[new ProductKey("ABC", 1)]);
    }
}

Coba Sendiri

Buktikan bahwa kontraknya terpenuhi: buat dua kunci yang sama dan pastikan keduanya memiliki kesamaan serta kode hash yang sama, lalu gunakan keduanya dalam set.

using System;
using System.Collections.Generic;

public struct Name
{
    public string First, Last;
    public Name(string first, string last) { First = first; Last = last; }
    public override bool Equals(object obj) => obj is Name n && n.First == First && n.Last == Last;
    public override int GetHashCode() => HashCode.Combine(First, Last);
}

public class Program
{
    public static void Main()
    {
        var a = new Name("Ada", "Lovelace");
        var b = new Name("Ada", "Lovelace");
        Console.WriteLine(a.Equals(b) + " " + (a.GetHashCode() == b.GetHashCode()));
        var people = new HashSet<Name> { a };
        Console.WriteLine(people.Contains(b));
    }
}

Pemeriksaan Singkat

Ingat kembali kontrak pembuatan hash.

Rangkuman

Pembuatan hash yang benar membuat koleksi berbasis hash tetap berfungsi.

  • Objek yang sama harus mengembalikan kode hash yang sama.
  • Gunakan HashCode.Combine pada bidang yang sama seperti dalam Equals.
  • Buat hash dari bidang yang tidak dapat diubah agar kunci tetap dapat ditemukan.
  • Tabrakan adalah hal yang wajar; Equals menyelesaikannya.
  • Record secara otomatis membuat penerapan yang benar.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Mengganti GetHashCode” gratis?

Ya — teks lengkap “Mengganti GetHashCode” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus C# Academy, upgrade ke CoddyKit PRO. Kursus C# Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Mengganti GetHashCode”?

Jaga konsistensi antara kesetaraan dan hashing. Kamu berlatih C# Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai C# Academy?

Tidak diperlukan pengalaman sebelumnya. C# Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Mengganti GetHashCode” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran C# Academy ini?

Ya. Setiap pelajaran C# Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mengimplementasikan IEquatable
  2. Mengganti GetHashCode
  3. Mengimplementasikan IComparable
  4. IComparer untuk Pengurutan Kustom
← Kembali ke C# Academy