Co należy nadpisać w strukturze, aby zapewnić prawidłowe działanie równości?
Jak mówi tytuł: Czy muszę nadpisać operator ==
? a co z metodą .Equals()
? Coś mi umknęło?
6 answers
Przykład z msdn
public struct Complex
{
double re, im;
public override bool Equals(Object obj)
{
return obj is Complex && this == (Complex)obj;
}
public override int GetHashCode()
{
return re.GetHashCode() ^ im.GetHashCode();
}
public static bool operator ==(Complex x, Complex y)
{
return x.re == y.re && x.im == y.im;
}
public static bool operator !=(Complex x, Complex y)
{
return !(x == y);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-01 07:50:18
Należy również zaimplementować IEquatable
Zaimplementuj IEquatable na typach wartości. Obiekt.Metoda równa na typy wartości powoduje boks, a jej Domyślna implementacja nie jest zbyt efektywna, ponieważ używa refekcji. / Align = "left" / Równi mogą oferować znacznie lepszą wydajność i mogą być zaimplementowany tak, aby nie powodował boksu.
public struct Int32 : IEquatable<Int32> {
public bool Equals(Int32 other){ ... }
}
Postępuj zgodnie z tymi samymi wytycznymi co dla nadpisuję obiekt.Równa się, gdy wdrożenie Ieequatable.Równi. Szczegółowe informacje znajdują się w sekcji 8.7.1 wytyczne dotyczące nadpisywania obiektu.Equals
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-01 07:52:44
Niestety nie mam dość reputacji, aby komentować inne wpisy. Więc zamieszczam ewentualne ulepszenia do najlepszego rozwiązania tutaj.
Popraw mnie, jeśli się mylę, ale implementacja wspomniana wyżej
public struct Complex
{
double re, im;
public override bool Equals(Object obj)
{
return obj is Complex && this == (Complex)obj;
}
public override int GetHashCode()
{
return re.GetHashCode() ^ im.GetHashCode();
}
public static bool operator ==(Complex x, Complex y)
{
return x.re == y.re && x.im == y.im;
}
public static bool operator !=(Complex x, Complex y)
{
return !(x == y);
}
}
Ma poważną wadę. Odwołuję się do
public override int GetHashCode()
{
return re.GetHashCode() ^ im.GetHashCode();
}
XORing jest symetryczny, więc złożone (2,1) i złożone(1,2) dałyby ten sam hashCode.
Powinniśmy zrobić coś bardziej jak:
public override int GetHashCode()
{
return re.GetHashCode() * 17 ^ im.GetHashCode();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-21 16:35:34
Przez większość czasu można unikać implementacji Equals i GetHashcode w strukturach - ponieważ kompilator automatycznie implementuje typy wartości używając bitowych elementów content + reflection dla elementów referencyjnych.
Zobacz ten post : która jest najlepsza dla struktury/klas przechowujących dane?
Więc dla ułatwienia można jeszcze wdrożyć = = i !=.
Ale przez większość czasu można uniknąć implementacji Equals i GetHashcode.
Przypadek, w którym musisz zaimplementować równe i GetHashCode jest dla pola, którego nie chcesz nie brać pod uwagę.
Na przykład pole, które zmienia się w miarę upływu czasu, jak wiek osoby lub instantSpeed samochodu (tożsamość obiektu nie powinna się zmieniać, jeśli chcesz znaleźć go z powrotem w słowniku w tym samym miejscu)
Pozdrawiam, najlepszy kod
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:26
Podstawowa różnica między tymi dwoma jest taka, że operator ==
jest statyczny, tzn. odpowiednia metoda do wywołania jest określana w czasie kompilacji, podczas gdy metoda Equals
jest wywoływana dinamicznie na instancji.
Definiowanie obu jest prawdopodobnie najlepszą rzeczą do zrobienia, nawet jeśli ma to mniejsze znaczenie w przypadku struktur, ponieważ struktury nie mogą być rozszerzane (struktura nie może dziedziczyć po innej).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-01 08:00:19
Tylko dla kompletności radziłbym też przeciążenie Equals
Metoda:
public bool Equals(Complex other)
{
return other.re == re && other.im == im;
}
Jest to prawdziwa poprawa spead, ponieważ nie występuje Boks argumentu wejściowego metody Equals(Object obj)
Niektóre najlepsze praktyki korzystania z typów wartości:
- uczyń je niezmiennymi
- override Equals (ten, który przyjmuje obiekt jako argument);
- przeciążenie równa się pobraniu innej instancji tego samego typu wartości(np. * Equals (Complex other));
- przeciążenie operatorzy = = i !=;
- override GetHashCode
To pochodzi z tego postu: http://theburningmonk.com/2015/07/beware-of-implicit-boxing-of-value-types/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-24 15:23:51