2010-03-20 9 views
5

Zadałem pytanie tutaj: When To Use IEquatable And Why o użyciu IEquatable.Czy ktoś wie, co stanie się, jeśli nie zaimplementujesz, jeśli korzystasz z ogólnych kolekcji?

Od MSDN:

Interfejs IEquatable (T) jest używany przez zbierania ogólnych obiektów, takich jak słowniku (TKey, TValue), lista (T) i LinkedList (T) podczas testowania równości w takich metod as Contains, IndexOf, LastIndexOf i Remove.

Jeśli nie zaimplementujesz tego interfejsu, co dokładnie się dzieje? Wyjątek/domyślny obiekt jest równy/równa się?

Odpowiedz

2

Oto jeden z przykładów:

public class Foo : IEquatable<Foo> 
{ 
    public string Bar { get; set; } 

    public bool Equals(Foo other) 
    { 
     return string.Equals(other.Bar, Bar); 
    } 
} 

class Program 
{ 

    public static void Main(string[] args) 
    { 
     var foos = new List<Foo>(new[] 
     { 
      new Foo { Bar = "b1" }, 
      new Foo { Bar = "b2" }, 
      new Foo { Bar = "b3" }, 
     }); 

     var foo = new Foo { Bar = "b2" }; 
     Console.WriteLine(foos.IndexOf(foo)); // prints 1 
    } 
} 

Teraz skomentować realizację IEquatable<Foo> i ponownie uruchomić program.

+1

Zgadza się, że zaakceptowana odpowiedź w rzeczywistości nie zawiera odpowiedzi ...;) – Guffa

+0

@Guffa, czasami przykład jest warty więcej niż tysiąc słów. Proszę nie zrozumcie mnie źle, myślę, że twoja odpowiedź jest doskonała, jasno wyjaśnia, w jaki sposób działa "IEquatable ". Chodzi o to, że kiedy dajesz przykład, na którym ludzie mogą grać, widzą, jak to działa w praktyce. –

+0

Czy istnieje szczególny punkt, aby pominąć wynik tego przykładu? – Guffa

4

Jeśli nie zostanie wdrożone porównanie równości, zostanie użyta domyślna implementacja.

Jeśli klucz jest typem odniesienia, używane jest porównanie odniesienia. O ile nie zachowasz kluczowych obiektów, aby można było ich używać podczas pobierania elementów z kolekcji, są one tracone. Utworzenie nowego obiektu klucza z tych samych danych daje obiekt z odwołaniem do różnicy, dzięki czemu nie pojawi się przedmiot, którego szukasz.

1

To trochę niepoprawne stwierdzenie, że Dictionary<TKey,TValue> używa IEquatable<T> do porównywania wartości TKey. W rzeczywistości używa on wartości IEquatilyComparer<T> do porównywania wartości.

Gdy jedno nie jest jawnie podane, ale będzie używać EqualityComparer<TKey>.Default do generowania porównania. Ta statyczna właściwość ma heurystykę określającą, który jest najlepszy sposób porównania wartości: TKey. Jeśli typ TKey implementuje IEqutable<TKey>, zostanie to użyte. Jeśli jednak tak się nie stanie, będzie korzystać z metody .Equals bezpośrednio.

Więc jeśli nie wdrożysz IEquatable<T> i nie zapewnisz wyraźności IEqualityComparer<T>, wtedy Dictionary<TKey,TValue> będzie opierać się na zwykłym .Equals.

Powiązane problemy