La principal diferencia entre IComparable y IComparable <> es que el primero es pre-genéricos de modo le permite llamar el método de comparar con cualquier objeto, mientras que el segundo hace cumplir que comparte el mismo tipo:
IComparable - CompareTo(object other);
IComparable<T> - CompareTo(T other);
Iría con la segunda opción, siempre que no tenga la intención de utilizar ninguna biblioteca .net 1.0 antigua donde los tipos no implementen la solución moderna y genérica. Obtendrás un aumento de rendimiento ya que evitarás el boxeo y las comparaciones no tendrán que comprobar la coincidencia de tipos y también obtendrás la sensación cálida que produce hacer las cosas de la manera más innovadora ...
Para abordar el punto muy bueno y pertinente de Jeff, yo diría que es una buena práctica colocar tan pocas restricciones en un genérico como se requiere para realizar la tarea. Como tiene el control completo del código dentro del genérico, sabe si está utilizando algún método que requiera un tipo básico de IComparable. Por lo tanto, tomando su comentario en consideración Yo personalmente seguir estas reglas:
Si no estás esperando el genérico de utilizar cualquier tipo que única implementan IComparable (es decir, el legado 1.0 código) y usted no está llamando a cualquiera los métodos del interior del genérico que se basan en un parámetro IComparable luego usan la restricción IComparable <> solamente.
Si está usando tipos que sólo implementan IComparable luego usar esa restricción única
Si está utilizando métodos que requieren un parámetro IComparable, pero no el uso de tipos que sólo implementan IComparable a continuación, utilizando tanto las limitaciones como en la respuesta de Jeff aumentará el rendimiento cuando utilice métodos que acepten el tipo genérico.
Para ampliar la tercera regla - Vamos a suponer que la clase que está escribiendo es como sigue:
public class StrangeExample<T> where ... //to be decided
{
public void SortArray(T[] input)
{
Array.Sort(input);
}
public bool AreEqual(T a, T b)
{
return a.CompareTo(b) == 0;
}
}
y tenemos que decidir qué restricciones para colocar en él. El método SortArray llama Array.Sort, que requiere que la matriz que se transfiere contenga objetos que implementan IComparable. Por lo tanto, imprescindible tenemos una restricción IComparable:
public class StrangeExample<T> where T : IComparable
Ahora la clase va a compilar y funcionar correctamente como una matriz de T es válida para Array.Sort y no es un método válido .CompareTo definido en la interfaz. Sin embargo, si está seguro de que usted no tendrá que usar su clase con un tipo que no tenga también implementar el IComparable <> interfaz puede extender su limitación a:
public class StrangeExample<T> where T : IComparable, IComparable<T>
Esto significa que cuando AreEqual se llamó utilizará el método CompareTo más rápido y genérico y verá un beneficio en el rendimiento a expensas de no poder usarlo con los viejos tipos de .NET 1.0.
Por otro lado, si no tiene el método AreEqual, entonces no hay ninguna ventaja en la restricción IComparable <>, por lo que también puede soltarlo; de todos modos, solo está utilizando implementaciones IComparable.
bruno: en su código, prefiero delegar el trabajo de comparación en CompareTo (objeto) a CompareTo (MyType) en la segunda rama de CompareTo (objeto), en lugar de duplicar el código. – Steve