Sobes.tech
Middle

Mit kell tenni ahhoz, hogy egy osztályt kulcsként használjunk egy gyűjteményben?

sobes.tech MI

Válasz az MI-től

Az osztályt kulcsként való használatához kollekcióban (például Dictionary<TKey, TValue>-ben) helyesen kell megvalósítani az Equals és GetHashCode metódusokat.

  1. Felülírni az Equals(object obj) metódust:

    • Összehasonlítani a jelenlegi példányt egy másik objektummal (obj) az egyenlőség ellenőrzéséhez.
    • Biztosítani kell, hogy obj ne legyen null.
    • Biztosítani kell, hogy obj ugyanazon típusú legyen, mint a jelenlegi példány.
    • Összehasonlítani mindkét objektum fontos mezőit vagy tulajdonságait.
  2. Felülírni a GetHashCode() metódust:

    • Olyan hash-kódot generálni, amely ugyanazokat a fontos mezőket vagy tulajdonságokat használja, mint az Equals.
    • Biztosítani kell, hogy ha az Equals két objektumra true-t ad, akkor azok GetHashCode értéke is ugyanaz legyen.
    • Ajánlott az egyenletes eloszlás a hash-kódok között a kollíziók csökkentése érdekében.
  3. Opcionálisan implementálni az IEquatable<T>-t:

    • Egy típusos Equals(T other) metódust biztosít, amely hatékonyabb lehet, mivel elkerüli a boxingot értéktípusok esetén.

Példa:

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

    // Felülírjuk az `Equals`-t érték szerinti összehasonlításhoz
    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;
    }

    // Felülírjuk a `GetHashCode()`-t ugyanazokkal a mezőkkel
    public override int GetHashCode()
    {
        // Tuple használata a hash kódok összekapcsolásához
        return (Id, Name).GetHashCode();
    }

    // Opcionálisan implementáljuk az `IEquatable<T>`-t
    public bool Equals(MyKey other)
    {
        if (other == null)
        {
            return false;
        }
        return Id == other.Id && Name == other.Name;
    }
}

A megfelelően implementálatlan ezek a metódusok esetén a Dictionary alapértelmezés szerint az identitás szerinti egyenlőséget (referencia összehasonlítás) és az alapértelmezett GetHashCode-t (amely referencia alapú) fogja használni, ami helytelen működéshez vezethet a kulcsok érték szerinti keresésekor.