Der Hauptunterschied zwischen IComparable und IComparable <> ist, dass die erste so vorge generics ist ermöglicht das Vergleichsverfahren mit einem Objekt zu nennen, während die zweiten erzwingt, dass sie die gleiche Art teilen:
IComparable - CompareTo(object other);
IComparable<T> - CompareTo(T other);
Ich würde mit der zweiten Option gehen vorausgesetzt, dass Sie keine alten .net 1.0-Bibliotheken verwenden möchten, wo die Typen die moderne, generische Lösung möglicherweise nicht implementieren. Sie werden einen Leistungsschub bekommen, weil Sie Boxen vermeiden und die Vergleiche müssen nicht überprüfen, ob die Typen übereinstimmen, und Sie werden auch das warme Gefühl bekommen, das von Dingen auf modernste Art und Weise kommt ...
Um Jeffs sehr guten und sachdienlichen Punkt anzusprechen, würde ich argumentieren, dass es eine gute Übung ist, so wenig Einschränkungen für ein generisches wie für die Ausführung der Aufgabe erforderlich zu machen. Da Sie die vollständige Kontrolle über den Code innerhalb des generischen Elements haben, wissen Sie, ob Sie Methoden verwenden, die einen grundlegenden IComparable-Typ erfordern. Also, seinen Kommentar zu berücksichtigen persönlich würde ich diese Regeln befolgen:
Wenn Sie nicht die generische erwarten alle Typen zu verwenden, die nur IComparable implementieren (dh Legacy 1.0-Code) und Sie rufen nicht Methoden innerhalb des generischen Objekts, die auf einem IComparable-Parameter basieren, verwenden dann nur die IComparable-Bedingung <>.
Wenn Sie sind Typen verwenden, die nur IComparable implementieren dann nur diese Einschränkung verwenden
Wenn Sie Methoden verwenden, die einen IComparable Parameter erfordern, aber nicht Typen verwenden, die nur implementieren IComparable dann beide Einschränkungen verwenden als In Jeffs Antwort wird die Leistung gesteigert, wenn Sie Methoden verwenden, die den generischen Typ akzeptieren.
auf der dritten Regel erweitern - nehmen wir an, dass die Klasse, die Sie schreiben, ist wie folgt:
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;
}
}
Und wir müssen entscheiden, welche Abhängigkeiten zu platzieren darauf. Die SortArray-Methode ruft Array.Sort auf, das erfordert, dass das Array, das übergeben wird, Objekte enthält, die IComparable implementieren. Deshalb wir Muss haben eine IComparable Einschränkung:
public class StrangeExample<T> where T : IComparable
Jetzt wird die Klasse kompiliert und korrekt funktioniert als ein Array von T gilt für Array.Sort ist und es eine gültige .CompareTo Methode in der Schnittstelle definiert. Wenn Sie jedoch sicher sind, dass Sie nicht mit einer Art verwenden, um Ihre Klasse wollen, die nicht auch die IComparable <> Schnittstelle nicht implementieren können Sie Ihre Einschränkung erweitern:
public class StrangeExample<T> where T : IComparable, IComparable<T>
Das bedeutet, dass, wenn AreEqual sie genannt wird Verwenden Sie die schnellere, generische CompareTo-Methode, und Sie werden einen Leistungsvorteil auf Kosten der alten .NET 1.0-Typen feststellen.
Auf der anderen Seite, wenn Sie nicht die AreEqual-Methode haben, gibt es keinen Vorteil für die IComparable <> -Constraint, so dass Sie es auch löschen können - Sie verwenden sowieso nur IComparable-Implementierungen.
bruno: In Ihrem Code würde ich eher den Vergleichsjob in CompareTo (Objekt) zu CompareTo (MyType) im zweiten Zweig von CompareTo (Objekt) delegieren, anstatt den Code zu duplizieren. – Steve