Autor Beitrag
lapadula
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: 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?

ausblenden volle Höhe 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 comparison
            DateTime x1, y1;
            // Parse the two objects passed as a parameter as a DateTime.
            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;

            //alphabetic comparison
            result = String.Compare(itemA.SubItems[Column].Text, itemB.SubItems[Column].Text);

        done:
            // if sort order is descending.
            if (Order == SortOrder.Descending)
                // Invert the value returned by Compare.
                result *= -1;
            return result;
        }
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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



BeitragVerfasst: Mo 30.01.17 13:56 
- Nachträglich durch die Entwickler-Ecke gelöscht -

Für diesen Beitrag haben gedankt: hydemarie, lapadula
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: 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:

ausblenden 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
    {
        //column used for comparison
        public int Column;
        public int ColumnGetSet
        {
            get { return Column; }
            set { Column = value; }
        }
        //Order of sorting
        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:

ausblenden volle Höhe 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;
                }
                //Wenn eine Sortierrichtung übergeben wurde, dann wird entsprechend sortiert.
                //Grund: wird ein Eintrag in einer ListView editiert oder neu anlegelgt, dann ändert sich die Sortierrichtung nicht ständig,
                //dies soll nur dann geschehen, wenn auf die Header geklickt wird, siehe else
                if (sortOrder == SortOrder.Descending)
                {
                    sorter.Column = Column;
                    sorter.Order = SortOrder.Descending;
                }
                else if (sortOrder == SortOrder.Ascending)
                {
                    sorter.Column = Column;
                    sorter.Order = SortOrder.Ascending;
                }
                else
                {
                    //Wenn keine Sortierrichtung übergeben wurde (SortOrder.None), 
                    //dann wechelt sich asc und desc ab (wenn auf den selben ColumnHeader geklickt wurde)
                    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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: Mo 30.01.17 15:07 
Habe das ganze nun so versucht:

ausblenden 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)
                    // Invert the value returned by Compare.
                    result *= -1;
                return result;
            }
            else
            {
                //alphabetic comparison
                result = String.Compare(itemA.SubItems[Column].Text, itemB.SubItems[Column].Text);
                return result;
            }


Leider sortiert er dann nicht mehr wie gewollt.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mo 30.01.17 15:51 
In dem else-Fall soll doch weiterhin auf SortOrder.Descending geprüft werden, also:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
if (x1 == DateTime.MinValue || y1 == DateTime.MinValue) // Gegenteil von != ... && ... != 
    result = String.Compare(itemA.SubItems[Column].Text, itemB.SubItems[Column].Text); //alphabetic comparison

// if sort order is descending.
if (Order == SortOrder.Descending)    
    result *= -1// // Invert the value returned by Compare.

return result;

Für diesen Beitrag haben gedankt: lapadula
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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.

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 475
Erhaltene Danke: 51



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: 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.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Mo 30.01.17 23:55 
:rofl:

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 475
Erhaltene Danke: 51



BeitragVerfasst: Di 31.01.17 00:01 
user profile iconlapadula hat folgendes geschrieben Zum zitierten Posting springen:
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:

Für diesen Beitrag haben gedankt: lapadula
lapadula Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 180
Erhaltene Danke: 10



BeitragVerfasst: 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
hydemarie
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 475
Erhaltene Danke: 51



BeitragVerfasst: Di 31.01.17 15:53 
user profile iconlapadula hat folgendes geschrieben Zum zitierten Posting springen:
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. :puke:

Für diesen Beitrag haben gedankt: lapadula
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: 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