entrambe le interfacce sembrano confrontare gli oggetti per l'uguaglianza, quindi quali sono le principali differenze tra loro?
entrambe le interfacce sembrano confrontare gli oggetti per l'uguaglianza, quindi quali sono le principali differenze tra loro?
Risposte:
IEquatable<T> per l'uguaglianza.
IComparable<T> per l'ordinazione.
Oltre alla risposta di Greg D:
Potresti implementarlo IComparablesenza implementarlo IEquatableper una classe in cui un ordinamento parziale ha senso e in cui vuoi decisamente che il consumatore deduca che solo perché CompareTo()restituisce zero, ciò non implica che gli oggetti siano uguali (per qualcosa di diverso dall'ordinamento).
IComparableè del tutto inappropriato qui. Quello che hai è un ordine molto particolare che si applica solo in una situazione speciale. In tali situazioni, l'implementazione di un generale IComparableè sbagliato. Questo è ciò IComparerper cui ci sono. Ad esempio, le persone non possono essere ordinate in modo significativo. Ma possono essere ordinati in base al loro stipendio, al numero di scarpe, al numero delle loro lentiggini o al loro peso. Quindi, implementeremmo IComparers differenti per tutti questi casi.
Come indicato nella pagina MSDN per IEquatable :
L'interfaccia IComparable definisce il
CompareTometodo, che determina l'ordinamento delle istanze del tipo di implementazione. L'interfaccia IEquatable definisce ilEqualsmetodo, che determina l'uguaglianza delle istanze del tipo di implementazione.
Equals vs. CompareTo
IComparable <T> definisce un metodo di confronto specifico per tipo che può essere utilizzato per ordinare o ordinare gli oggetti.
IEquatable <T> definisce un metodo generalizzato che può essere utilizzato per implementare per determinare l'uguaglianza.
Diciamo che hai una classe Persona
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Person p1 = new Person() { Name = "Person 1", Age = 34 };
Person p2 = new Person() { Name = "Person 2", Age = 31 };
Person p3 = new Person() { Name = "Person 3", Age = 33 };
Person p4 = new Person() { Name = "Person 4", Age = 26 };
List<Person> people = new List<Person> { p1, p2, p3, p4 };
people.Sort();.Ma questo genererà un'eccezione.
Framework non sa come ordinare questi oggetti. Devi dire come ordinare l' IComparableinterfaccia di implementazione .
public class Person : IComparable
{
public string Name { get; set; }
public int Age { get; set; }
public int CompareTo(object obj)
{
Person otherPerson = obj as Person;
if (otherPerson == null)
{
throw new ArgumentNullException();
}
else
{
return Age.CompareTo(otherPerson.Age);
}
}
}
Questo ordinerà correttamente l'array con il Sort()metodo.
Equals()metodo.var newPerson = new Person() { Name = "Person 1", Age = 34 };
var newPersonIsPerson1 = newPerson.Equals(p1);
Ciò torneràfalse perché il Equalsmetodo non sa come confrontare due oggetti. Pertanto è necessario implementare l' IEquatableinterfaccia e indicare al framework come eseguire il confronto. Estendendo l'esempio precedente sembrerà questo.
public class Person : IComparable, IEquatable<Person>
{
//Some code hidden
public bool Equals(Person other)
{
if (Age == other.Age && Name == other.Name)
{
return true;
}
else
{
return false;
}
}
}
IEquatableusa un generico<Person> e IComparableno?
IComparablecorrettamente. Si può venire con un esempio significativo in cuiCompareTo(…) == 0non non implica l'uguaglianza? Di certo non posso. In effetti, il contratto di interfaccia (come per MSDN) richiede che ciòCompareTo(…) == 0implichi l'uguaglianza. Per dirla senza mezzi termini, in un caso come il tuo, usa unComparatoroggetto speciale , non implementareIComparable.