Sobes.tech
Middle

Cosa bisogna fare per usare una classe come chiave in una collezione?

sobes.tech AI

Risposta dell'AI

Per utilizzare una classe come chiave in una collezione (ad esempio, in Dictionary<TKey, TValue>), è necessario implementare correttamente i metodi Equals e GetHashCode.

  1. Sovrascrivere Equals(object obj):

    • Confrontare l’istanza corrente con un altro oggetto (obj) per verificare l’uguaglianza.
    • Assicurarsi che obj non sia null.
    • Assicurarsi che obj abbia lo stesso tipo dell’istanza corrente.
    • Confrontare i campi o le proprietà rilevanti di entrambi gli oggetti.
  2. Sovrascrivere GetHashCode():

    • Generare un codice hash basato sugli stessi campi o proprietà rilevanti usati in Equals.
    • Garantire che se Equals restituisce true per due oggetti, i loro metodi GetHashCode restituiscano lo stesso valore.
    • È consigliabile distribuire uniformemente i codici hash per ridurre le collisioni.
  3. Implementare opzionalmente IEquatable<T>:

    • Fornisce un metodo tipizzato Equals(T other), che può essere più efficiente evitando il boxing per i tipi di valore.

Esempio:

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

    // Sovrascrivere Equals per confronto sui valori
    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;
    }

    // Sovrascrivere GetHashCode usando gli stessi campi
    public override int GetHashCode()
    {
        // Usare Tuple per combinare gli hash
        return (Id, Name).GetHashCode();
    }

    // Implementazione opzionale di IEquatable<T>
    public bool Equals(MyKey other)
    {
        if (other == null)
        {
            return false;
        }
        return Id == other.Id && Name == other.Name;
    }
}

Senza una corretta implementazione di questi metodi, Dictionary utilizzerà di default l’uguaglianza di identità (confronto di riferimenti) e l’implementazione predefinita di GetHashCode (basata sul riferimento), il che può portare a un funzionamento errato della collezione durante la ricerca di chiavi per valore.