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 IComparable
senza implementarlo IEquatable
per 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ò IComparer
per 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 IComparer
s differenti per tutti questi casi.
Come indicato nella pagina MSDN per IEquatable :
L'interfaccia IComparable definisce il
CompareTo
metodo, che determina l'ordinamento delle istanze del tipo di implementazione. L'interfaccia IEquatable definisce ilEquals
metodo, 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' IComparable
interfaccia 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 Equals
metodo non sa come confrontare due oggetti. Pertanto è necessario implementare l' IEquatable
interfaccia 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;
}
}
}
IEquatable
usa un generico<Person>
e IComparable
no?
IComparable
correttamente. Si può venire con un esempio significativo in cuiCompareTo(…) == 0
non non implica l'uguaglianza? Di certo non posso. In effetti, il contratto di interfaccia (come per MSDN) richiede che ciòCompareTo(…) == 0
implichi l'uguaglianza. Per dirla senza mezzi termini, in un caso come il tuo, usa unComparator
oggetto speciale , non implementareIComparable
.