Middle
Co należy zrobić, aby użyć klasy jako klucza w kolekcji?
sobes.tech AI
Odpowiedź od AI
Aby używać klasy jako klucza w kolekcji (np. w Dictionary<TKey, TValue>), konieczne jest poprawne zaimplementowanie metod Equals i GetHashCode.
-
Nadpisanie
Equals(object obj):- Porównanie bieżącego obiektu z innym obiektem (
obj) w celu sprawdzenia równości. - Upewnienie się, że
objnie jestnull. - Upewnienie się, że
objma ten sam typ co bieżący obiekt. - Porównanie istotnych pól lub właściwości obu obiektów.
- Porównanie bieżącego obiektu z innym obiektem (
-
Nadpisanie
GetHashCode():- Wygenerowanie kodu hash na podstawie tych samych istotnych pól lub właściwości, które są używane w
Equals. - Zapewnienie, że jeśli
Equalszwracatruedla dwóch obiektów, to ichGetHashCodezwraca tę samą wartość. - Zaleca się równomierne rozłożenie kodów hash, aby zmniejszyć kolizje.
- Wygenerowanie kodu hash na podstawie tych samych istotnych pól lub właściwości, które są używane w
-
Opcjonalnie implementacja
IEquatable<T>:- Udostępnia typowaną metodę
Equals(T other), która może być bardziej wydajna, unikając boxing dla typów wartości.
- Udostępnia typowaną metodę
Przykład:
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;
}
// Nadpisanie Equals do porównania po wartościach
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;
}
// Nadpisanie GetHashCode z użyciem tych samych pól
public override int GetHashCode()
{
// Użycie Tuple do łączenia hashów
return (Id, Name).GetHashCode();
}
// Opcjonalnie implementacja IEquatable<T>
public bool Equals(MyKey other)
{
if (other == null)
{
return false;
}
return Id == other.Id && Name == other.Name;
}
}
Bez poprawnej implementacji tych metod, domyślnie Dictionary będzie używał równości tożsamości (porównanie referencji) i domyślnej implementacji GetHashCode (opartej na referencji), co może prowadzić do nieprawidłowego działania kolekcji podczas wyszukiwania kluczy po wartościach.