Réponses:
Eh bien, ils ne sont pas tout à fait la même chose que celle IComparer<T>
implémentée sur un type capable de comparer deux objets différents alors qu'elle IComparable<T>
est implémentée sur des types capables de se comparer avec d'autres instances du même type.
J'ai tendance à utiliser IComparable<T>
lorsque j'ai besoin de savoir comment une autre instance se rapporte à une this
instance. IComparer<T>
est utile pour trier les collections en IComparer<T>
dehors de la comparaison.
IComparable
que je suis comparable . ce qui signifie que je peux être comparé à autre chose. Et lu IComparer
comme je suis un comparateur, je compare simplement ce qui signifie que je compare certaines choses.
Cela dépend de l'entité. Par exemple suivant pour une classe comme "Student", il sera logique d'avoir IComparable basé sur Name.
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);
}
}
Mais si un enseignant «A» veut comparer des élèves sur la base de MathScore et que l'enseignant «B» veut comparer des élèves sur la base de EnglishScore. Ce sera une bonne idée d'implémenter IComparer séparément. (Plus comme un modèle de stratégie)
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;
}
}
Tout dépend si votre type est mutable ou non. Vous devez seulement mettre en œuvre IComparable sur les types non-mutables. Notez que si vous implémentez IComparable, vous devez remplacer Equals, ainsi que les opérateurs ==,! =, <Et> (voir l'avertissement d'analyse de code CA1036).
Citant Dave G à partir de ce billet de blog :
Mais la bonne réponse est d'implémenter IComparer au lieu de IComparable si vos objets sont mutables et de transmettre une instance de IComparer aux fonctions de tri si nécessaire.
Étant donné que IComparer n'est qu'un objet jetable utilisé pour le tri à ce moment-là, votre objet peut avoir n'importe quelle sémantique modifiable que vous souhaitez. De plus, il ne nécessite ni ne suggère d'utiliser Equals, GetHashCode ou == - vous êtes libre de le définir de la manière qui vous convient.
Enfin, vous pouvez définir plusieurs IComparer pour votre type pour le tri sur différents champs ou avec des règles différentes. C'est beaucoup plus flexible que d'être coincé avec une définition.
En bref: utilisez IComparable pour les types valeur et IComparer pour les types référence.
Explication simple via une histoire
Basket-ball de lycée. C'est un choix de cour d'école pour les équipes. Je veux obtenir les personnes les plus grandes / les meilleures / les plus rapides de mon équipe. Que fais-je?
Interface IComparer - Comparez deux personnes différentes
Compare(Fred, John)
et il crache qui est le meilleur.Et IComparable? - Comparez-vous avec quelqu'un d'autre
Avez-vous été sur FB récemment? Vous voyez d'autres gens faire des choses sympas: parcourir le monde, créer des inventions, pendant que je fais quelque chose qui n'est pas aussi cool - eh bien, ce que nous faisons, c'est utiliser l'interface IComparable.
Qu'en est-il de la classe Comparer?
La classe Comparer est une classe de base abstraite qui implémente l'interface IComparer. Vous devez dériver de cette classe pour avoir une implémentation concrète. Quoi qu'il en soit, Microsoft vous recommande d'utiliser la classe Comparer plutôt que d'implémenter l'interface IComparer:
Nous vous recommandons de dériver de la classe Comparer au lieu d'implémenter l'interface IComparer, car la classe Comparer fournit une implémentation d'interface explicite de la méthode IComparer.Compare et de la propriété Default qui obtient le comparateur par défaut pour l'objet.
J'espère que les histoires vous aideront à vous souvenir.
Comme d'autres l'ont dit, ils ne font pas la même chose.
Dans tous les cas, ces jours-ci, j'ai tendance à ne pas utiliser IComparer. Pourquoi aurais-je? Sa responsabilité (une entité externe utilisée pour comparer deux objets) peut être gérée beaucoup plus clairement avec une expression lambda, similaire au fonctionnement de la plupart des méthodes LINQ. Écrivez un lambda rapide qui prend les objets à comparer comme arguments, et renvoie un booléen. Et si l'objet définit sa propre opération de comparaison intrinsèque, il peut implémenter IComparable à la place.
IComparable dit qu'un objet peut être comparé à un autre. IComparer est un objet qui peut comparer deux éléments quelconques.
IComparer est une interface qui permet de trier le tableau, cette interface forcera la classe à implémenter la méthode Compare (T x, T y), qui comparera les deux objets. L'instance de la classe qui a implémenté cette interface est utilisée dans le tri du tableau.
IComparable est une interface implémentée dans le type qui a besoin de comparer les deux objets du même type, Cette interface comparable forcera la classe à implémenter la méthode suivante CompareTo (T obj)
IEqualityComparer est une interface qui est utilisée pour trouver l'objet, qu'il soit égal ou non, nous allons maintenant le voir dans un exemple où nous devons trouver le distinct d'un objet dans une collection. Cette interface implémentera une méthode Equals (T obj1, T obj2)
Maintenant, nous prenons un exemple, nous avons une classe Employee, basée sur cette classe, nous devons créer une collection. Nous avons maintenant les exigences suivantes.
Trier le tableau à l'aide de la classe Array 2. Besoin d'une collection utilisant Linq: supprimer le duplicata, classer par ordre décroissant, supprimer un identifiant d'employé
abstract public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { set; get; }
}
public enum SortType
{
ByID,
BySalary
}
Classe publique EmployeeIdSorter: IComparer {public int Compare (Employee x, Employee y) {if (x.Id <y.Id) return 1; else if (x.Id> y.Id) return -1; sinon retourne 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;
}
}
Pour plus d'informations, référez-vous ci-dessous http://dotnetvisio.blogspot.in/2015/12/usage-of-icomparer-icomparable-and.html