Risposte:
Ebbene non sono proprio la stessa cosa in quanto IComparer<T>
è implementato su un tipo che è in grado di confrontare due oggetti diversi mentre IComparable<T>
è implementato su tipi che sono in grado di confrontarsi con altre istanze dello stesso tipo.
Tendo a usare IComparable<T>
per i momenti in cui ho bisogno di sapere come un'altra istanza si riferisce this
all'istanza. IComparer<T>
è utile per l'ordinamento delle collezioni in quanto le IComparer<T>
posizioni fuori dal confronto.
IComparable
come sono paragonabile . il che significa che posso essere paragonato a qualcos'altro. E leggi IComparer
come sono un comparatore, semplicemente confronto, il che significa che confronto alcune cose.
Dipende dall'entità. Ad esempio, seguendo per una classe come "Studente", avrà senso avere IComparable basato su Nome.
class Student : IComparable
{
public string Name { get; set; }
public int MathScore { get; set; }
public int EnglishScore { get; set; }
public int TotalScore
{
get
{
return this.MathScore + this.EnglishScore;
}
}
public int CompareTo(object obj)
{
return CompareTo(obj as Student);
}
public int CompareTo(Student other)
{
if (other == null)
{
return 1;
}
return this.Name.CompareTo(other.Name);
}
}
Ma se un insegnante "A" desidera confrontare gli studenti in base a MathScore e l'insegnante "B" desidera confrontare gli studenti in base a EnglishScore. Sarà una buona idea implementare IComparer separatamente. (Più simile a un modello strategico)
class CompareByMathScore : IComparer<Student>
{
public int Compare(Student x, Student y)
{
if (x.MathScore > y.MathScore)
return 1;
if (x.MathScore < y.MathScore)
return -1;
else
return 0;
}
}
Tutto dipende dal fatto che il tuo tipo sia mutevole o meno. È necessario implementare IComparable solo sui tipi non modificabili. Si noti che se si implementa IComparable, è necessario sostituire Equals, insieme agli operatori ==,! =, <E> (vedere l'avviso di analisi del codice CA1036).
Citando Dave G da questo post del blog :
Ma la risposta corretta è implementare IComparer invece di IComparable se gli oggetti sono modificabili e passare un'istanza di IComparer alle funzioni di ordinamento quando necessario.
Poiché IComparer è solo un oggetto usa e getta utilizzato per l'ordinamento in quel momento, il tuo oggetto può avere qualsiasi semantica mutabile che desideri. Inoltre, non richiede né suggerisce l'uso di Equals, GetHashCode o ==: sei libero di definirlo nel modo che preferisci.
Infine, puoi definire più IComparer per il tuo tipo per l'ordinamento su campi diversi o con regole diverse. Questo è molto più flessibile dell'essere bloccati con una definizione.
In breve: utilizzare IComparable per i tipi di valore e IComparer per i tipi di riferimento.
Spiegazione semplice tramite una storia
Pallacanestro del liceo. È una scelta del cortile della scuola per le squadre. Voglio avere le persone più alte / migliori / più veloci nella mia squadra. Cosa faccio?
Interfaccia IComparer : confronta due persone separate
Compare(Fred, John)
e sputa chi è il migliore.Che mi dici di IComparable? - Confronta te stesso con qualcun altro
Sei stato su FB di recente? Vedi altre persone che fanno cose interessanti: viaggiare per il mondo, creare invenzioni, mentre io sto facendo qualcosa di non altrettanto interessante - beh, quello che stiamo facendo è usare l'interfaccia IComparable.
E la classe Comparer?
La classe Comparer è una classe base astratta che implementa l'interfaccia IComparer. Dovresti derivare da questa classe per avere un'implementazione concreta. comunque, Microsoft consiglia di utilizzare la classe Comparer anziché implementare l'interfaccia IComparer:
Si consiglia di derivare dalla classe Comparer invece di implementare l'interfaccia IComparer, poiché la classe Comparer fornisce un'implementazione dell'interfaccia esplicita del metodo IComparer.Compare e della proprietà Default che ottiene l'operatore di confronto predefinito per l'oggetto.
Spero che le storie ti aiutino a ricordare.
Come altri hanno già detto, non fanno la stessa cosa.
In ogni caso, in questi giorni tendo a non usare IComparer. Perché dovrei? La sua responsabilità (un'entità esterna usata per confrontare due oggetti) può essere gestita in modo molto più pulito con un'espressione lambda, simile a come funzionano la maggior parte dei metodi di LINQ. Scrivi un lambda veloce che prenda gli oggetti da confrontare come argomenti e restituisca un valore bool. E se l'oggetto definisce la propria operazione di confronto intrinseca, può invece implementare IComparable.
IComparable dice che un oggetto può essere paragonato a un altro. IComparer è un oggetto che può confrontare due elementi qualsiasi.
IComparer è un'interfaccia che viene utilizzata per ordinare l'Array, questa interfaccia costringerà la classe a implementare il metodo Compare (T x, T y), che confronterà i due oggetti. L'istanza della classe che ha implementato questa interfaccia viene utilizzata nell'ordinamento di Array.
IComparable è un'interfaccia implementata nel tipo che deve confrontare i due oggetti dello stesso tipo, questa interfaccia comparabile costringerà la classe a implementare il seguente metodo CompareTo (T obj)
IEqualityComparer è un'interfaccia che viene utilizzata per trovare l'oggetto che sia uguale o meno, ora lo vedremo in un esempio in cui dobbiamo trovare il Distinct di un oggetto in una raccolta. Questa interfaccia implementerà un metodo Equals (T obj1, T obj2)
Ora prendiamo un esempio, abbiamo una classe Employee, in base a questa classe dobbiamo creare una Collection. Ora abbiamo i seguenti requisiti.
Ordina la matrice utilizzando la classe Array 2. Serve una raccolta utilizzando Linq: Rimuovi il duplicato, Ordina dal più alto al più basso, Rimuovi un ID dipendente
abstract public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { set; get; }
}
public enum SortType
{
ByID,
BySalary
}
public class EmployeeIdSorter: IComparer {public int Compare (Employee x, Employee y) {if (x.Id <y.Id) return 1; altrimenti se (x.Id> y.Id) restituisce -1; altrimenti restituisce 0; }}
public class EmployeeSalarySorter : IComparer<Employee>
{
public int Compare(Employee x, Employee y)
{
if (x.Salary < y.Salary)
return 1;
else if (x.Salary > y.Salary)
return -1;
else
return 0;
}
}
Per maggiori informazioni fare riferimento a http://dotnetvisio.blogspot.in/2015/12/usage-of-icomparer-icomparable-and.html