Respuestas:
Bueno, no son exactamente lo mismo que IComparer<T>
se implementa en un tipo que es capaz de comparar dos objetos diferentes, mientras que IComparable<T>
se implementa en tipos que pueden compararse con otras instancias del mismo tipo.
Tiendo a usarlo IComparable<T>
para momentos en los que necesito saber cómo se relaciona otra instancia con la this
instancia. IComparer<T>
es útil para clasificar colecciones como los IComparer<T>
soportes fuera de la comparación.
IComparable
como soy comparable . lo que significa que puedo compararme con otra cosa. Y IComparer
como soy un comparador, simplemente comparo, lo que significa que comparo algunas cosas.
Depende de la entidad. Por ejemplo, siguiendo para una clase como "Estudiante", tendrá sentido tener IComparable basado en Nombre.
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);
}
}
Pero si un profesor 'A' quiere comparar a los estudiantes en función de MathScore, y el profesor 'B' quiere comparar a los estudiantes en función de EnglishScore. Será una buena idea implementar IComparer por separado. (Más como un patrón de estrategia)
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;
}
}
Todo depende de si tu tipo es mutable o no. Usted debe solamente aplicar IComparable de tipos no mutables. Tenga en cuenta que si implementa IComparable, debe anular Equals, junto con los operadores ==,! =, <Y> (consulte la advertencia de análisis de código CA1036).
Citando a Dave G de esta publicación de blog :
Pero la respuesta correcta es implementar IComparer en lugar de IComparable si sus objetos son mutables y pasar una instancia de IComparer a las funciones de clasificación cuando sea necesario.
Dado que IComparer es solo un objeto desechable que se utiliza para clasificar en ese momento, su objeto puede tener cualquier semántica mutable que desee. Además, no requiere ni sugiere el uso de Equals, GetHashCode o ==; puede definirlo como desee.
Finalmente, puede definir múltiples IComparer para su tipo para clasificar en diferentes campos o con diferentes reglas. Esto es mucho más flexible que quedarse atascado con una definición.
En resumen: use IComparable para tipos de valor e IComparer para tipos de referencia.
Explicación simple a través de una historia
Baloncesto de secundaria. Es una selección de patio de la escuela para los equipos. Quiero tener a las personas más altas / mejores / más rápidas en mi equipo. ¿Qué debo hacer?
Interfaz IComparer : compare dos personas por separado
Compare(Fred, John)
y escupe quién es mejor.¿Qué pasa con IComparable? - Compárate con alguien más
¿Has estado en FB recientemente? Ves a otras personas haciendo cosas interesantes: viajar por el mundo, crear inventos, mientras yo hago algo que no es tan genial, bueno, lo que estamos haciendo es utilizar la interfaz IComparable.
¿Qué pasa con la clase Comparer?
La clase Comparer es una clase base abstracta que implementa la interfaz IComparer. Debes derivar de esta clase para tener una implementación concreta. de todos modos, Microsoft recomienda que use la clase Comparer en lugar de implementar la interfaz IComparer:
Recomendamos que se derive de la clase Comparer en lugar de implementar la interfaz IComparer, porque la clase Comparer proporciona una implementación de interfaz explícita del método IComparer.Compare y la propiedad Default que obtiene el comparador predeterminado para el objeto.
Espero que las historias te ayuden a recordar.
Como han dicho otros, no hacen lo mismo.
En cualquier caso, estos días no suelo usar IComparer. ¿Por qué habría? Su responsabilidad (una entidad externa utilizada para comparar dos objetos) se puede manejar de manera mucho más limpia con una expresión lambda, similar a cómo funcionan la mayoría de los métodos de LINQ. Escriba una lambda rápida que tome los objetos para compararlos como argumentos y devuelva un bool. Y si el objeto define su propia operación de comparación intrínseca, puede implementar IComparable en su lugar.
IComparable dice que un objeto se puede comparar con otro. IComparer es un objeto que puede comparar dos elementos cualesquiera.
IComparer es una interfaz que se utiliza para ordenar el Array, esta interfaz obligará a la clase a implementar el método Compare (T x, T y), que comparará los dos objetos. La instancia de la clase que implementó esta interfaz se usa en la clasificación del Array.
IComparable es una interfaz implementada en el tipo que necesita comparar los dos objetos del mismo tipo. Esta interfaz comparable obligará a la clase a implementar el siguiente método CompareTo (T obj)
IEqualityComparer es una interfaz que se usa para encontrar el objeto, sea igual o no. Ahora veremos esto en una muestra donde tenemos que encontrar el Distinto de un Objeto en una colección. Esta interfaz implementará un método Equals (T obj1, T obj2)
Ahora tomamos un ejemplo, tenemos una clase de empleado, en base a esta clase tenemos que crear una colección. Ahora tenemos los siguientes requisitos.
Ordene la matriz usando la clase de matriz 2. Necesita una colección usando Linq: eliminar el duplicado, ordenar de mayor a menor, eliminar una identificación de empleado
abstract public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { set; get; }
}
public enum SortType
{
ByID,
BySalary
}
clase pública EmployeeIdSorter: IComparer {public int Compare (Empleado x, Empleado y) {if (x.Id <y.Id) return 1; else if (x.Id> y.Id) return -1; de lo contrario, devuelve 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;
}
}
Para obtener más información, consulte a continuación http://dotnetvisio.blogspot.in/2015/12/usage-of-icomparer-icomparable-and.html