Zaobserwowany tu problem jest szczególnym przypadkiem bardziej ogólnego problemu, polegającego na tym, że liczba różnych definicji równości, które mogą być przydatne przynajmniej w niektórych okolicznościach, przekracza liczbę powszechnie dostępnych sposobów ich wyrażenia. W niektórych przypadkach ten problem pogarsza niefortunne przekonanie, że mylące jest posiadanie różnych metod testowania równości, które dają różne wyniki, a takiego zamieszania można uniknąć, jeśli różne formy równości dają takie same wyniki, kiedy tylko jest to możliwe.
W rzeczywistości podstawową przyczyną nieporozumień jest błędne przekonanie, że należy oczekiwać, że różne formy testowania równości i nierówności dadzą ten sam wynik, niezależnie od faktu, że różne semantyki są przydatne w różnych okolicznościach. Na przykład, z arytmetycznego punktu widzenia, warto mieć możliwość porównania, Decimal
które różnią się tylko liczbą końcowych zer, jako równe. Podobnie dla double
wartości takich jak dodatnie zero i ujemne zero. Z drugiej strony, z punktu widzenia buforowania lub internowania, taka semantyka może być śmiertelna. Załóżmy na przykład, że ktoś ma Dictionary<Decimal, String>
taki, który myDict[someDecimal]
powinien być równy someDecimal.ToString()
. Taki przedmiot wydawałby się rozsądny, gdyby ktoś miał ich wieleDecimal
wartości, które ktoś chciał przekonwertować na łańcuch i spodziewał się wielu duplikatów. Niestety, gdyby wykorzystano takie buforowanie do konwersji 12,3 mi 12,40 m, a następnie 12,30 mi 12,4 m, te ostatnie wartości dałyby „12,3” i „12,40” zamiast „12,30” i „12,4”.
Wracając do omawianej sprawy, istnieje więcej niż jeden rozsądny sposób porównywania obiektów dopuszczających wartość zerową pod kątem równości. C # przyjmuje stanowisko, że jego ==
operator powinien odzwierciedlać zachowanie Equals
. VB.NET stoi na stanowisku, że jego zachowanie powinno odzwierciedlać zachowanie niektórych innych języków, ponieważ każdy, kto chce, Equals
może użyć tego zachowania Equals
. W pewnym sensie właściwym rozwiązaniem byłoby posiadanie trójczynnikowej konstrukcji „jeśli” i wymaganie, aby jeśli wyrażenie warunkowe zwracało trójwartościowy wynik, kod musiał określać, co powinno się wydarzyć w null
przypadku. Ponieważ nie jest to możliwe w przypadku języków, którymi są, kolejną najlepszą alternatywą jest po prostu nauczenie się, jak działają różne języki i uznanie, że nie są one tym samym.
Nawiasem mówiąc, operator „Is” języka Visual Basic, którego brakuje w C, może służyć do testowania, czy obiekt dopuszczający wartość null jest w rzeczywistości pusty. Chociaż można rozsądnie zastanawiać się, czy if
test powinien akceptować a Boolean?
, użyteczną funkcją jest zwracanie normalnych operatorów porównania Boolean?
zamiast Boolean
wywoływania ich na typach dopuszczających wartość null. Nawiasem mówiąc, w VB.NET, jeśli ktoś spróbuje użyć operatora równości zamiast Is
, otrzyma ostrzeżenie, że wynik porównania zawsze będzie Nothing
i należy go użyć, Is
jeśli chce się sprawdzić, czy coś jest zerowe.