Entwickler-Ecke
Basistechnologien - goto-Anweisung umgehen
lapadula - Mo 30.01.17 13:38
Titel: goto-Anweisung umgehen
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?
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: 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 - 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?
Delete - Mo 30.01.17 13:56
- Nachträglich durch die Entwickler-Ecke gelöscht -
Ralf Jansen - 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.
lapadula - 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:
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: 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 - 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 - 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; |
Ralf Jansen - 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; |
lapadula - 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 - 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.
lapadula - 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. - Mo 30.01.17 23:55
:rofl:
Ralf Jansen - 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.
hydemarie - Di 31.01.17 00:01
lapadula hat folgendes geschrieben : |
Ich hab irgendwo gelesen das das nutzen der goto Anweisung ein Kündigungsgrund sei. |
Hängt von der Sprache ab. Schreib' mal ein Assemblerprogramm ohne Sprung. :twisted:
lapadula - 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 :D
OlafSt - 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 ;)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!