Sobes.tech
Middle

Čo je potrebné urobiť, aby ste mohli použiť triedu ako kľúč v kolekcii?

sobes.tech AI

Odpoveď od AI

Ak chcete použiť triedu ako kľúč v kolekcii (napríklad v Dictionary<TKey, TValue>), je potrebné správne implementovať metódy Equals a GetHashCode.

  1. Prekryť Equals(object obj):

    • Porovnať aktuálny inštanciu s iným objektom (obj) na rovnosť.
    • Uistiť sa, že obj nie je null.
    • Uistiť sa, že obj má rovnaký typ ako aktuálny inštanciu.
    • Porovnať dôležité polia alebo vlastnosti oboch objektov.
  2. Prekryť GetHashCode():

    • Vygenerovať hash kód na základe tých istých dôležitých polí alebo vlastností, ktoré sa používajú v Equals.
    • Zaručiť, že ak Equals vráti true pre dva objekty, ich metódy GetHashCode vrátia rovnakú hodnotu.
    • Ideálne zabezpečiť rovnomerné rozloženie hash kódov na zníženie kolízií.
  3. Voliteľne implementovať IEquatable<T>:

    • Poskytuje typizovanú metódu Equals(T other), ktorá môže byť výkonnejšia, vyhýbajúc sa baleniu (boxing) pre hodnotové typy.

Prí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;
    }

    // Prekrytie Equals na porovnanie podľa hodnôt polí
    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;
    }

    // Prekrytie GetHashCode, využívajúce tie isté polia
    public override int GetHashCode()
    {
        // Používame Tuple pre jednoduché kombinovanie hash kódov
        return (Id, Name).GetHashCode();
    }

    // Voliteľne implementujeme IEquatable<T>
    public bool Equals(MyKey other)
    {
        if (other == null)
        {
            return false;
        }
        return Id == other.Id && Name == other.Name;
    }
}

Bez správnej implementácie týchto metód bude Dictionary predvolene používať rovnosť identity (porovnanie odkazov) a predvolenú implementáciu GetHashCode (založenú na odkaze), čo povedie k nesprávnej práci kolekcie pri vyhľadávaní kľúčov podľa hodnoty.