Sobes.tech
Middle

Co je třeba udělat, aby bylo možné třídu použít jako klíč v kolekci?

sobes.tech AI

Odpověď od AI

Chcete-li třídu použít jako klíč v kolekci (například v Dictionary<TKey, TValue>), je nutné správně implementovat metody Equals a GetHashCode.

  1. Přepsat Equals(object obj):

    • Porovnat aktuální instanci s jiným objektem (obj) na rovnost.
    • Ujistit se, že obj není null.
    • Ujistit se, že obj má stejný typ jako aktuální instance.
    • Porovnat důležitá pole nebo vlastnosti obou objektů.
  2. Přepsat GetHashCode():

    • Vygenerovat hash kód na základě stejných důležitých polí nebo vlastností používaných v Equals.
    • Zajistit, že pokud Equals vrací true pro dva objekty, jejich GetHashCode metody vrací stejnou hodnotu.
    • Doporučuje se rovnoměrné rozložení hash kódů ke snížení kolizí.
  3. Volitelně implementovat IEquatable<T>:

    • Poskytuje typovanou metodu Equals(T other), která může být efektivnější, protože se vyhýbá boxingu u hodnotových typů.

Příklad:

using System;
using System.Collections.Generic;

public class MyKey
{
    public int Id { get; }
    public string Name { get; }

    public MyKey(int id, string name)
    {
        Id = id;
        Name = name;
    }

    // Přepsat `Equals` pro porovnání podle hodnot
    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
        {
            return false;
        }

        MyKey other = (MyKey)obj;
        return Id == other.Id && Name == other.Name;
    }

    // Přepsat `GetHashCode` s použitím stejných polí
    public override int GetHashCode()
    {
        // Použití Tuple pro kombinování hash kódů
        return (Id, Name).GetHashCode();
    }

    // Volitelně implementovat `IEquatable<T>`
    public bool Equals(MyKey other)
    {
        if (other == null)
        {
            return false;
        }
        return Id == other.Id && Name == other.Name;
    }
}

Bez správné implementace těchto metod bude Dictionary ve výchozím nastavení používat rovnost identity (porovnání odkazů) a výchozí implementaci GetHashCode (založenou na odkazu), což může vést k nesprávnému fungování kolekce při hledání klíčů podle hodnoty.