diferencia entre IComparable y IComparer

¿Cuál es la diferencia entre IComparable e IComparer Interfaces? ¿Es necesario utilizar esta interfaz siempre con el método Array.Sort()

Como su nombre indica, IComparable dice que soy comparable . IComparable cuando se define para T permite comparar la instancia actual con otra instancia del mismo tipo. IComparer dice que soy un comparador, lo comparo . IComparer se usa para comparar dos instancias de T , generalmente fuera del scope de las instancias de T

En cuanto a lo que son, puede ser confuso al principio. A partir de la definición, debe quedar claro que, por tanto, IComparable (definido en la propia clase T ) debería ser el estándar de facto para proporcionar la lógica para la clasificación. La List Sort por defecto List etc. se basa en esto. La implementación de IComparer en T no ayuda a la clasificación regular. Posteriormente, hay poco valor para implementar IComparable en cualquier otra clase que no sea T Esta:

 class MyClass : IComparable 

raramente tiene sentido.

Por otra parte

 class T : IComparable { public int CompareTo(T other) { //.... } } 

es cómo debería hacerse.

IComparer puede ser útil cuando requiera ordenamiento basado en un pedido personalizado, pero no como una regla general. Por ejemplo, en una clase de Person en algún momento puede requerir Clasificar personas según su edad. En ese caso, puedes hacer:

 class Person { public int Age; } class AgeComparer : IComparer { public int Compare(Person x, Person y) { return x.Age - y.Age; } } 

Ahora, AgeComparer ayuda a ordenar una lista basada en la Age .

 var people = new Person[] { new Person { age = 23 }, new Person(){ age = 22 } }; people.Sort(p, new AgeComparer()); //person with age 22 comes first now. 

Del IComparer modo IComparer en T no tiene sentido.

 class Person : IComparer 

Es cierto que esto funciona, pero no se ve bien a los ojos y derrota la lógica.

Usualmente lo que necesitas es IComparable . También idealmente puede tener solo un IComparable mientras que el IComparer múltiple IComparer es posible en función de diferentes criterios.

El IComparer y el IComparable son exactamente análogos a IEqualityComparer y IEquatable que se utilizan para probar la igualdad en lugar de comparar / clasificar; un buen hilo aquí donde escribí exactamente la misma respuesta 🙂

  • IComparable: define una interfaz para un objeto con un método CompareTo () que toma otro objeto del mismo tipo y compara el objeto actual con el pasado. Se internaliza la comparación con el objeto, lo que permite una operación de comparación más en línea, y es útil cuando hay una sola forma lógica, o una manera predeterminada abrumadoramente común, para comparar objetos de un tipo.
  • IComparer: define una interfaz con un método Compare () que toma dos objetos de otro tipo (que no tienen que implementar IComparable) y los compara. Esto externaliza la comparación, y es útil cuando hay muchas maneras factibles de comparar dos objetos de un tipo, o cuando el tipo no implementa IComparable (o la implementación IComparable se compara de una manera diferente a la que desea) y usted no tener control sobre la fuente de ese tipo.

La mejor explicación que he leído es “El objeto que se va a ordenar implementará IComparable, mientras que la clase que va a ordenar los objetos implementará IComparer”. ( fuente )

Si los objetos que intenta ordenar no implementan IComparable, deberá crear una clase que implemente IComparer (y acepte esos tipos de objetos para comparación) y pasarlo al método Array.Sort ().

IComparable se usa para proporcionar un orden de clasificación predeterminado para sus objetos.

IComparer es proporcionar mecanismos de comparación adicionales.

vea este artículo para referencia. http://support.microsoft.com/kb/320727

IComparer compara dos objetos que se le dan. IComparable se implementa por el objeto que se compara, con el fin de comparar con otro de sí mismo.

Es una buena idea implementar IComparable para clasificar objetos. IComparable puede ser útil para ordenar por diferentes criterios (por ejemplo, ordenar por un campo seleccionable en el objeto).

Ver también: Cuándo usar IComparable Vs. IComparer

Los objetos que son instancias de clases que implementan IComparable se pueden comparar con otros objetos. (Lea IComparable como “Se me puede comparar”). El método en esta interfaz que hace esto es CompareTo . Esto es útil si desea que instancias de tales clases sepan cómo compararse con otros objetos.

Los objetos que son instancias de clases que implementan IComparer se pueden usar para comparar pares de objetos. (Lea IComparer como “Puedo comparar”). El método en esta interfaz que hace esto es Compare . Esto es útil si desea desacoplar la lógica de comparación de la clase de objetos que se comparan. Un caso en el que puede usar esto si tiene varias formas de comparar objetos (estas comparaciones de cadenas insensibles a mayúsculas y minúsculas).