Ich fülle ein Array mit Instanzen einer Klasse:
BankAccount[] a;
. . .
a = new BankAccount[]
{
new BankAccount("George Smith", 500m),
new BankAccount("Sid Zimmerman", 300m)
};
Sobald ich dieses Array ausgefüllt habe, möchte ich es nach Saldobeträgen sortieren. Dazu möchte ich prüfen können, ob jedes Element mit sortierbar ist IComparable
.
Ich muss dies über Schnittstellen tun. Bisher habe ich folgenden Code:
public interface IComparable
{
decimal CompareTo(BankAccount obj);
}
Ich bin mir aber nicht sicher, ob dies die richtige Lösung ist. Irgendein Rat?
quelle
return this.Balance.CompareTo(that.Balance);
public class BankAccount : IComparable<BankAccount> { [...] int CompareTo(BankAccount that) { return this.Balance.CompareTo(that.Balance); } }
Ist das klarer?return Balance - that.Balance;
this.Balance < that.Balance
nach aufsteigendem Saldo zu sortieren. -1 = das ist weniger als das, 0 = das ist gleich das, 1 = das ist größer als dasreturn Balance - that.Balance
ist keine gute Idee, wenn sich die Waage jemals den Grenzen ihres Typs nähert, da ein Überlauf zu falschen Ergebnissen führen kann. Wenn beispielsweise Balance a wäreshort
undthis.Balance
32700 undthat.Balance
-100 wäre, wäre das Ergebnis der Subtraktion -32736, wenn das ErgebnisCompareTo
eindeutig eine positive Zahl sein sollte. In ähnlicher Weise kannushort
das Ergebnis der Subtraktion niemals negativ sein , wenn Balance a ist , was ebenfalls eindeutig falsch ist.Möchten Sie das Array destruktiv sortieren? Das heißt, möchten Sie die Reihenfolge der Elemente im Array tatsächlich ändern? Oder möchten Sie nur eine Liste der Artikel in einer bestimmten Reihenfolge, ohne die ursprüngliche Reihenfolge zu zerstören?
Ich würde vorschlagen, dass es fast immer besser ist, Letzteres zu tun. Erwägen Sie die Verwendung von LINQ für eine zerstörungsfreie Bestellung. (Und erwägen Sie die Verwendung eines aussagekräftigeren Variablennamens als "a".)
BankAccount[] bankAccounts = { whatever }; var sortedByBalance = from bankAccount in bankAccounts orderby bankAccount.Balance select bankAccount; Display(sortedByBalance);
quelle
null
beim ImplementierenIComparable<T>
und Unterklassen unter derComparer<T>
Annahme, dassT
es sich um einen Referenztyp handelt? Hängt es vom Benutzerfall ab oder ist es normalerweise besser, eine Ausnahme auszulösen, da die reale Vergleichslogik häufig an eine Eigenschaft weitergeleitet wirdT
.IComparable
existiert bereits in .NET mit dieser Definition von CompareToint CompareTo(Object obj)
Sie sollen die Schnittstelle nicht erstellen - Sie sollen sie implementieren.
public class BankAccount : IComparable { int CompareTo(Object obj) { // return Less than zero if this object // is less than the object specified by the CompareTo method. // return Zero if this object is equal to the object // specified by the CompareTo method. // return Greater than zero if this object is greater than // the object specified by the CompareTo method. } }
quelle
null
oder von einem anderen Typ alsBankAccount
? EDIT: Laut MSDN hier: msdn.microsoft.com/en-us/library/… : werfen Sie eineArgumentException
.Eine Alternative besteht darin, LINQ zu verwenden und die Implementierung von IComparable insgesamt zu überspringen:
quelle
Es gibt bereits
IComparable<T>
, aber Sie sollten idealerweise beideIComparable<T>
und unterstützenIComparable
. Die Verwendung des eingebautenComparer<T>.Default
ist im Allgemeinen eine einfachere Option.Array.Sort
akzeptiert beispielsweise einen solchen Vergleicher.quelle
Wenn Sie diese nur sortieren müssen
BankAccounts
, verwenden SieLINQ
FolgendesBankAccount[] a = new BankAccount[] { new BankAccount("George Smith", 500m), new BankAccount("Sid Zimmerman", 300m) }; a = a.OrderBy(bank => bank.Balance).ToArray();
quelle