0Pricing
C# Academy · Ders

GetHashCode'u Geçersiz Kılma

Eşitlik ve karma işlemlerini tutarlı tutun.

GetHashCode'u Geçersiz Kılma, CoddyKit'te ücretsiz bir C# Academy dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C# Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C# Academy kursu toplamda 4 dersten oluşur.

GetHashCode Neden Önemlidir

Dictionary ve HashSet gibi karma tabanlı koleksiyonlar, öğeleri kovalarına yerleştirmek için GetHashCode yöntemini kullanır. Equals yöntemini geçersiz kılıp GetHashCode yöntemini geçersiz kılmazsanız bu koleksiyonlar eşit öğeleri bulamayabilir.

Altın Kural

Sözleşme basittir: İki nesne eşitse, aynı karma kodunu döndürmelidir. Tersi gerekli değildir; farklı nesneler aynı karma kodunu paylaşabilir (çakışma).

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());
    }
}

HashCode.Combine Kullanın

HashCode.Combine yardımcısı, çeşitli alan değerlerini iyi dağıtılmış bir karma kodunda birleştirir. GetHashCode uygulamak için önerilen modern yöntem budur.

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());
    }
}

Eşitlik ile Karma İşlemini Birlikte Ele Alın

Equals ve GetHashCode yöntemlerini her zaman aynı alanları kullanarak birlikte geçersiz kılın. Farklı alanlar kullanmak, eşit nesnelerin farklı karma kodları üretmesine neden olur.

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());
    }
}

Sözlüklerin Buna Neden İhtiyacı Var

Bir Dictionary önce kovayı bulmak için anahtarı karma işleminden geçirir, ardından bu kova içinde Equals yöntemini kullanır. Yanlış bir karma kodu aramayı yanlış kovaya yönlendirir ve anahtar hiçbir zaman bulunamaz.

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)]);
    }
}

Değişmez Alanları Karma İşleminden Geçirme

Karma kodları, bir nesne karma koleksiyonunda bulunduğu sürece sabit kalmalıdır. Karma kodunu değişmez alanları temel alarak oluşturun; bir anahtar eklendikten sonra değişirse koleksiyon anahtarın izini kaybedebilir.

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());
    }
}

Boş Alanları Ele Alma

Bir alan boş olabiliyorsa HashCode.Combine bunu güvenli biçimde ele alır. Hesaplamayı kendiniz yapıyorsanız NullReferenceException oluşmasını önlemek için boş değerleri kontrol edin.

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());
    }
}

Çakışmalar Normaldir

Karma kodları 32 bit olduğundan, büyük veri kümelerinde çakışmalar kaçınılmazdır. İyi bir karma işlevi değerleri yalnızca çakışmaları seyrek tutacak şekilde dağıtır; oluşan çakışmaları Equals çözer.

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));
    }
}

Kayıtlar Bunu Sizin İçin Üretir

Bir record, özelliklerinden doğru bir GetHashCode yöntemini otomatik olarak üretir ve bunu değer tabanlı Equals yöntemiyle uyumlu tutar. Karma işlemini doğru yapmanın en kolay yolu budur.

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)));
    }
}

Doğru Bir Eşitlenebilir Tür

Her şeyi bir araya getirelim: Equals ve GetHashCode içinde aynı alanlar, değişmez anahtarlar ve birleştirme için HashCode.Combine. Bu tür, sözlük anahtarı olarak kusursuz çalışır.

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)]);
    }
}

Kendiniz Deneyin

Sözleşmenin geçerli olduğunu kanıtlayın: Eşit iki anahtar oluşturup hem eşitliklerinin hem de karma kodlarının aynı olduğunu doğrulayın, ardından bunları bir kümede kullanın.

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));
    }
}

Hızlı Kontrol

Karma işlemi sözleşmesini hatırlayın.

Özet

Doğru karma işlemi, karma tabanlı koleksiyonların çalışmasını sağlar.

  • Eşit nesneler aynı karma kodunu döndürmelidir.
  • Equals ile aynı alanlar üzerinde HashCode.Combine kullanın.
  • Anahtarların bulunabilir kalması için değişmez alanları karma işleminden geçirin.
  • Çakışmalar normaldir; bunları Equals çözer.
  • Kayıtlar doğru uygulamayı otomatik olarak üretir.

Sıkça Sorulan Sorular

“GetHashCode'u Geçersiz Kılma” dersi ücretsiz mi?

Evet — “GetHashCode'u Geçersiz Kılma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C# Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C# Academy kursu toplamda 4 dersten oluşur.

“GetHashCode'u Geçersiz Kılma” dersinde ne öğreneceğim?

Eşitlik ve karma işlemlerini tutarlı tutun. C# Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

C# Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te C# Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.

“GetHashCode'u Geçersiz Kılma” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu C# Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her C# Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. IEquatable Uygulama
  2. GetHashCode'u Geçersiz Kılma
  3. IComparable Uygulama
  4. Özel Sıralama için IComparer
← C# Academy Sayfasına Dön