Autor |
Beitrag |
lapadula
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Mo 30.01.17 13:38
Hallo, ich bin auf diese compare-Methode aus dem Internet gestoßen. Diese funktioniert wunderbar aber ich habe mir sagen lassen, dass die goto-Anweisung veraltet ist bzw. ein schlechter Programmier-Stil ist, da es unübersichtlich werden kann beim debuggen.
Ich habe das ganze versucht mit einer while-Schleife zu "übersetzen". Leider funktioniert dann das die Methode nicht richtig.
Kann mir einer sagen wie ich das sonst machen soll?
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| public int Compare(object a, object b) { int result; ListViewItem itemA = a as ListViewItem; ListViewItem itemB = b as ListViewItem; if (itemA == null && itemB == null) result = 0; else if (itemA == null) result = -1; else if (itemB == null) result = 1; if (itemA == itemB) result = 0; DateTime x1, y1; if (!DateTime.TryParse(itemA.SubItems[Column].Text, out x1)) x1 = DateTime.MinValue; if (!DateTime.TryParse(itemB.SubItems[Column].Text, out y1)) y1 = DateTime.MinValue;
result = DateTime.Compare(x1, y1);
if (x1 != DateTime.MinValue && y1 != DateTime.MinValue) goto done;
result = String.Compare(itemA.SubItems[Column].Text, itemB.SubItems[Column].Text);
done: if (Order == SortOrder.Descending) result *= -1; return result; } |
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 30.01.17 13:51
Da ist eine if Anweisung. In einem Fall soll der string returned werden mit dem alphabetic comparison Kommentar und im anderen Fall das was in done passiert. Ein if und 2.Möglichkeiten was muß man wohl tun?
Für diesen Beitrag haben gedankt: lapadula
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 30.01.17 13:56
- Nachträglich durch die Entwickler-Ecke gelöscht -
Für diesen Beitrag haben gedankt: hydemarie, lapadula
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 30.01.17 14:00
Der ItemSorter für einen ListView muß aber IComparer auf ein ListViewItem implementieren. Ich vermute mal dazu gehört das Codebruchstück.
Für diesen Beitrag haben gedankt: lapadula
|
|
lapadula
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Mo 30.01.17 14:55
@Ralf danke ich probier das mal aus.
@Frühlingsrolle ich werde den Sortierer im nächsten Projekt selber schreiben, bis dahin lasse ich es so. Es funktioniert bestens.
Da fehlt noch die Klasse:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| public class ItemComparer : IComparer { public int Column; public int ColumnGetSet { get { return Column; } set { Column = value; } } public SortOrder Order; public SortOrder OrderGetSet { get { return Order; } set { Order = value; } } public ItemComparer(int colIndex) { Column = colIndex; Order = SortOrder.None; } public int Compoare (object a, object b) { ... } |
Und die Methode die ich aufrufe um zu sortieren:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
| static public void Sort(ListView listView, int Column, SortOrder sortOrder) { if (listView != null) { ItemComparer sorter = listView.ListViewItemSorter as ItemComparer; if (sorter == null) { sorter = new ItemComparer(Column); sorter.Order = SortOrder.Ascending; listView.ListViewItemSorter = sorter; } if (sortOrder == SortOrder.Descending) { sorter.Column = Column; sorter.Order = SortOrder.Descending; } else if (sortOrder == SortOrder.Ascending) { sorter.Column = Column; sorter.Order = SortOrder.Ascending; } else { if (Column == sorter.Column) { if (sorter.Order == SortOrder.Ascending) sorter.Order = SortOrder.Descending; else sorter.Order = SortOrder.Ascending; } else { sorter.Column = Column; sorter.Order = SortOrder.Ascending; } } listView.Sort(); } } |
|
|
lapadula
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Mo 30.01.17 15:07
Habe das ganze nun so versucht:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| if (x1 != DateTime.MinValue && y1 != DateTime.MinValue) { if (Order == SortOrder.Descending) result *= -1; return result; } else { result = String.Compare(itemA.SubItems[Column].Text, itemB.SubItems[Column].Text); return result; } |
Leider sortiert er dann nicht mehr wie gewollt.
|
|
Th69
Beiträge: 4777
Erhaltene Danke: 1054
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mo 30.01.17 15:51
In dem else-Fall soll doch weiterhin auf SortOrder.Descending geprüft werden, also:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| if (x1 == DateTime.MinValue || y1 == DateTime.MinValue) result = String.Compare(itemA.SubItems[Column].Text, itemB.SubItems[Column].Text); if (Order == SortOrder.Descending) result *= -1; return result; |
Für diesen Beitrag haben gedankt: lapadula
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 30.01.17 16:06
Ich habe mich glaube ich missverständlich ausgedrückt ich wollte eigentlich das du schon viel früher abbiegst.
Das basteln mit DateTime.MinDate ist schon überflüssig.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| DateTime x1, y1; if (DateTime.TryParse(itemA.SubItems[Column].Text, out x1) && DateTime.TryParse(itemB.SubItems[Column].Text, out y1)) result = DateTime.Compare(x1, y1); else result = String.Compare(itemA.SubItems[Column].Text, itemB.SubItems[Column].Text);
if (Order == SortOrder.Descending) result *= -1; return result; |
Für diesen Beitrag haben gedankt: lapadula
|
|
lapadula
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Mo 30.01.17 17:00
@Th69 Danke so klappts.
Muss mir das nochmal in Ruhe anschauen
@Ralf Danke für den Ratschlag, ich werde die Methode dann doch nochmal umschreiben müssen.
|
|
hydemarie
Beiträge: 481
Erhaltene Danke: 51
|
Verfasst: Mo 30.01.17 21:09
Pro forma: Ein "goto" hat natürlich seine Berechtigung - intern macht der Compiler auch nix anderes. Man muss nicht unbedingt komplizierteren Code schreiben als nötig. Aber ab einer gewissen Komplexität wird es durchaus empfohlen, stattdessen Methoden zu verwenden.
Für diesen Beitrag haben gedankt: lapadula
|
|
lapadula
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Mo 30.01.17 23:44
Ich hab irgendwo gelesen das das nutzen der goto Anweisung ein Kündigungsgrund sei.
Bei Erfahrenen Entwicklern nehme ich an
|
|
Christian S.
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Mo 30.01.17 23:55
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Di 31.01.17 00:00
In den Best Practises steht sicher irgendwas von vermeiden von goto. Das ist auch fast immer richtig. Es gibt aber Fälle wo es sinnvoll sein kann goto zu benutzen .
Beispiele:
* Schwer lesbare mehrfache verschachtelter Schleifen. Wenn ich aus der innersten Schleife raus muss kann ein goto helfen das lesbar zu halten.
* cases in Switch Statements wo ein einfacher fallthrough nicht ausreicht und man zu einem case Label direkt springt
Natürlich macht man das aber erst (mit Bauchschmerzen) nachdem man genau die Alternativen durchdacht hat. Meist gibt es auch gut lesbare Alternativen, eigentlich sogar meist besser lesbare Alternativen, es gibt aber eben auch diese Fälle wo ein erzwingen einer Alternative es nur schlimmer macht anstatt besser.
Für diesen Beitrag haben gedankt: lapadula
|
|
hydemarie
Beiträge: 481
Erhaltene Danke: 51
|
Verfasst: Di 31.01.17 00:01
Für diesen Beitrag haben gedankt: lapadula
|
|
lapadula
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Di 31.01.17 15:35
Mit Assembler kenne ich mich nicht aus aber Java hat goto auch irgendwann mal verbannt.
Die Sache mit dem Kündigungsgrund hat ein User auf stackoverflow erzählt, hatte den Eindruck er meint es ernst
|
|
hydemarie
Beiträge: 481
Erhaltene Danke: 51
|
Verfasst: Di 31.01.17 15:53
lapadula hat folgendes geschrieben : | Java hat goto auch irgendwann mal verbannt. |
Nun sollte man Java natürlich nicht unbedingt als lobendes Beispiel für irgendwas verwenden. Und tatsächlich kann Java stattdessen etwas viel Schlimmeres: break und continue mit Label.
Für diesen Beitrag haben gedankt: lapadula
|
|
OlafSt
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Mi 01.02.17 11:25
Ich programmiere nun schon ein paar Tage... In den 80er Jahren, auf den Homecomputern C64, Schneider CPC, TI-99 4/A usw. waren die Basic-Dialekte noch sehr rudimentär. Dort hatte man gar keine Wahl und mußte mit GOTO arbeiten. Als dann die ersten Dialekte mit GOSUB-Anweisungen kamen und auch verbesserte Schleifenkonstrukte mit DO..WHILE eingeführt wurden, verbesserte sich das ganze sehr.
Lasse ich diese Dinosaurier-Zeiten mal außen vor, habe ich in all den Jahrzehnten nur einen einzigen, wirklich notwendigen Fall für ein GOTO gesehen. Das war ein C-Programm, eine riesige, mehrfach verschachtelte Schleife, die sich über etliche hundert Zeilen zog und nur über ein GOTO sauber "mittendrin" verlassen werden konnte. Ansonsten habe ich nie wieder einen Anwendungsfall für GOTO gefunden.
Die Schleife zu entzerrren und aufs GOTO zu verzichten, hätte uns sicher drei Tage Arbeit gemacht. Wir haben uns lange im Team angesehen und überlegt - jeder hatte ein schmerzverzerrtes Gesicht, als wir uns fürs GOTO entschieden. So sehr sind wir indoktriniert, kein GOTO zu verwenden
_________________ Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
Für diesen Beitrag haben gedankt: lapadula
|
|