c# im dritten Anlauf



  • hustbaer schrieb:

    string dagegen ist ein Value-Type, und der kann direkt in der ArrayList gespeichert werden.

    Bloß ein Schreibfehler, aber nicht dass es noch jemand glaubt: string ist natürlich ein Referenz-Typ.



  • Der Weg zu C# ist schon steinig. Man kann auch nicht immer alles irgendwo googlen. Im Moment geht es trotz googeln an diesem Punkt nicht weiter:

    Es wird eine Liste erstellt List<ClassPerson> mit string Name und int nr und aufgefüllt mit einigen Datensätzen. Diese Liste soll nun von der aufrufenden Methode weiterverarbeitet bzw. benutzt werden, und was ich nicht hinkriege, ist die Zuweisung.

    Wenn List<ClassPerson> als Rückgabewert mit return zurückkommt, und in der aufrufenden Methode eine List<ClassPerson> mit new definiert ist, kann ich mit List1=handle.fuelleListe() = Rückgabewert der Funktion nicht zuweisen, obwohl innerhalb derselben Methode List1=List2 durchaus funktioniert (da aber keinen Sinn macht).

    Übergabe mit ref oder out?

    Vom Praktischen her wäre das Problem in WinForms schon gelöst, da ich z. B. listBox1 mit den Daten aus der Datei füttern und via SelectedItem in der ganzen WinForms-Umgebung problemlos benutzen kann (wenn auch nur im string-Format, also ständig hin- und herverwandeln). Eine Liste mit strukturierten Daten wäre das Gewünschte.

    In Ansi-C wäre es überhaupt kein Problem ... lassen wir das. Das führt hier nicht weiter.

    Mir fehlt im Moment wirklich die zündende Idee. 😮

    Pascal

    PS: Die Ansi-C-Denke (soll bzw. muß ja ausgemerzt werden, aber kleines Beispiel, was ich eigentlich will). Der Code hier ist aus einem laufenden Programm, was ich für die FiBu benutze. Das ist eine dynamische Liste zu Fuß programmiert, die eine Binärdatei einliest, Datenelement ist eine struct, übergeben wird die Startadresse des ersten Elements der Liste (da wäre natürlich List in C# einiges einfacher, wenn man es denn mal verstanden hätte):

    struct s_element *kopiere_datei_in_liste(char *dname)
    {
            struct s_element *listenkopf=NULL;       
            struct s_element *laufzeiger=NULL;
            struct s_bsatz buffer;     
            FILE *bdp;
            bdp=fopen(dname,"rb");
            if (bdp==NULL){meldung("Kann Datei",dname,"nicht oeffnen");return;}
            while (fread(&buffer,sizeof(struct s_bsatz),1,bdp)==1)
            {
               if (listenkopf==NULL){listenkopf=element_anhaengen(listenkopf);laufzeiger=listenkopf;}
               else laufzeiger=element_anhaengen(laufzeiger);
               laufzeiger->data=buffer;
            }                         
          fclose(bdp);  
          return listenkopf;
    }
    

    Element anhängen ist so definiert (im Grunde ist der Code C# und AnsiC irgendwo von der Logik sehr ähnlich, fast schadet es aber von AnsiC nach C#, weil die Ähnlichkeit eben nur oberflächlich ist, wahrscheinlich besser, man würde bei 0 anfangen, jedenfalls Z. B. malloc und new da sticht die Ähnlichkeit ja wirklich ins Auge:

    struct s_element *element_anhaengen(struct s_element *vorgaenger)
    {
        struct s_element *neues;
        neues=malloc(sizeof(struct s_element));
        neues->next=NULL;
        if (vorgaenger==NULL) neues->prev=NULL;
        else {neues->prev=vorgaenger;vorgaenger->next=neues;}
        return neues;
    }
    


  • List<ClassPerson> fuelleListe()
    {
        var list = new List<ClassPerson> ();
        list.Add(new ClassPerson("Name1", 0));
        list.Add(new ClassPerson("Name2", 1));
        return list;
    }
    
    void methodTest()
    {
        List<ClassPerson> list = fuelleListe();
    }
    

    Meinst du so ? 😕



  • DarkShadow44 schrieb:

    List<ClassPerson> fuelleListe()
    {
        var list = new List<ClassPerson> ();
        list.Add(new ClassPerson("Name1", 0));
        list.Add(new ClassPerson("Name2", 1));
        return list;
    }
    
    void methodTest()
    {
        List<ClassPerson> list = fuelleListe();
    }
    

    Meinst du so ? 😕

    Ich probiere... neu ist dabei der Typ var, hatte ich vorher nicht.

    Deinen Code habe ich jetzt so umgesetzt:

    In der Klasse CL_Konten:

    public class CL_Konten
        {
    
            public class CL_Konto
            {
                public int kontonr;
                public string kontobez;
                public double eroeffnung;
                public double abschluss;
                public char art;
            };
    
            public List<CL_Konto> init_Kontenrahmen()
            {
                var kontenliste = new List<CL_Konto>();
                kontenliste.Add(new CL_Konto { kontonr = 4900, kontobez = "Sonstige Kosten" });
                kontenliste.Add(new CL_Konto { kontonr = 4920, kontobez = "Telefon" });
    
                return kontenliste;
            }
    
        }
    

    Aufruf von WinForms Form1:

    public Form1()
            {
    /*
                InitializeComponent();
                DateTime d = DateTime.Now;
                akt_jahr=d.Year;
                akt_monat = d.Month;
                akt_tag = d.Day;
    
                lfd_jahr=akt_jahr;
                label3.Text = lfd_jahr.ToString();
    */  
    
                CL_Konten kn = new CL_Konten();
                List<CL_Konten> list = kn.init_Kontenrahmen();
    
                MessageBox.Show("Beendet");
    
            }
    

    meckert der Compiler: eine implizite Konvertierung ist nicht möglich ... das hat er vorher bei meinen hundert Versuchen auch immer getan. Hab ich was übersehen?

    Pascal

    PS:

    Hier ist die exakte Fehlermeldung:

    Fehler 1 Eine implizite Konvertierung vom Typ "System.Collections.Generic.List<Fibu2014Version1._1.CL_Konten.CL_Konto>" in "System.Collections.Generic.List<Fibu2014Version1._1.CL_Konten>" ist nicht möglich. C:\Users\Chief\Desktop\Programmierung in C#\Fibu2014Version1.1\Fibu2014Version1.1\Form1.cs 32 36 Fibu2014Version1.1



  • CL_Konto != CL_Konten

    Du gibst eine List<CL_Konto> zurück und willst sie einer Referenz auf List<CL_Konten> zuweisen.



  • µ schrieb:

    CL_Konto != CL_Konten

    Du gibst eine List<CL_Konto> zurück und willst sie einer Referenz auf List<CL_Konten> zuweisen.

    Tausendmal probiert, tausendmal ist nix passiert.

    Ich brauche 2 Handles!

    Tatsächlich, so gegen Mitternacht am nächsten Tag, es geht was:

    public Form1()
            {
                InitializeComponent();
    /*
                DateTime d = DateTime.Now;
                akt_jahr=d.Year;
                akt_monat = d.Month;
                akt_tag = d.Day;
    
                lfd_jahr=akt_jahr;
                label3.Text = lfd_jahr.ToString(); */
    
                CL_Konten          k1 = new CL_Konten();         // Handle 1
                CL_Konten.CL_Konto k2 = new CL_Konten.CL_Konto();// Handle 2
    
                List<CL_Konten.CL_Konto> list = k1.init_Kontenrahmen();
                MessageBox.Show(list[0].kontobez);
                MessageBox.Show("Beendet");
    
            }
    

    ............... macht er genau das, was er soll. 🤡

    Soll das einer verstehen!

    Also wenn jemals jemand sagen würde, C# wäre einfach zu verstehen, dann laß ich mich in die nächste Anstalt einliefern .............. ich hab größte Probleme mit der C# Denke. Ohne die WIN Oberfläche wär ich bei Ansi geblieben, aber das ist Historie ... 😉

    Pascal

    PS: bzw. den handle 2 kann man auch knicken, man muß ihn nur gedanklich berücksichtigen. So denken als ob. Also wenn man den rausnimmt und die Liste auf der zweiten Ebene deklariert mit

    List<CL_Konten.CL_Konto> list = k1.init_Kontenrahmen();

    geht es auch ohne ihn. Auf der tieferen Ebene, wo man die Liste kriegt, würde man aber nicht die Methode kriegen, die liegt ja eine Ebene höher.

    Wie auch immer, es funktioniert! Nix verstanden aber Problem gelöst, ist doch auch was. 🤡



  • pascal2009 schrieb:

    Die einzig logische Erklärung dafür wäre, daß die Liste die Elemente gar nicht speichert, sondern lediglich einen Adressoperator auf den Speicherplatz von kbuf enthält.

    Das ist auch genau so. Hängt aber nicht mit der Liste zusammen. Das ist allgemein so wenn man mit Reference Typen arbeitet.

    Sie funktioniert also nicht als Liste, sondern nur als Zeiger. Was mach ich falsch?

    Du hast C# nicht verstanden.
    Bzw. allgemein den Unterschied zwischen Value Typen und Reference Typen.
    Bei Reference Typen (class) gibt's nur so viele Objekte wie oft nur "new" sagt.



  • GPC schrieb:

    hustbaer schrieb:

    string dagegen ist ein Value-Type, und der kann direkt in der ArrayList gespeichert werden.

    Bloß ein Schreibfehler, aber nicht dass es noch jemand glaubt: string ist natürlich ein Referenz-Typ.

    Hab's korrigiert, danke!



  • pascal2009 schrieb:

    Also wenn jemals jemand sagen würde, C# wäre einfach zu verstehen, dann laß ich mich in die nächste Anstalt einliefern .............. ich hab größte Probleme mit der C# Denke.

    Dir fehlen die ganzen Grundlagen (nicht auf C# bezogen, sondern auf die Programmierung allgemein!). Und so setzt du dich hin und willst ne neue Sprache mit "learning by doing" lernen. Irgendwie klar dass das nicht funktioniert.



  • hustbaer schrieb:

    pascal2009 schrieb:

    Also wenn jemals jemand sagen würde, C# wäre einfach zu verstehen, dann laß ich mich in die nächste Anstalt einliefern .............. ich hab größte Probleme mit der C# Denke.

    Dir fehlen die ganzen Grundlagen (nicht auf C# bezogen, sondern auf die Programmierung allgemein!). Und so setzt du dich hin und willst ne neue Sprache mit "learning by doing" lernen. Irgendwie klar dass das nicht funktioniert.

    Ich hab ganz nette Grundlagen in Ansi-C. Das hab ich glaube ich ziemlich gut begriffen, von der Denke. Hätte Ansi-C eine GUI, wär ich gar nicht hier.

    Beim Umstieg auf C#:

    Problem ist die OOP-Denke.
    Davon abgeleitet, die Sichtbarkeit der Methoden und Variablen, das Problem gibt es in C überhaupt so nicht (daß es nämlich der Compiler vorschreibt).
    .NET ist sehr gut, Klasse, aber: mit den tausend Funktionen muß man sich ja erstmal vertraut machen.
    Mit der WinForms und WPF komme ich dagegen überraschend gut zurecht (dank VisualStudio), was ja auch nicht schwierig ist, wovor ich aber zuvor den größten Respekt hatte. Tatsächlich ist WinForms einfacher als die eigentliche Sprache C#.

    Jetzt habe ich mir sogar noch ein zweites Buch gekauft, aber glaub nicht, daß in den Büchern das drin steht, was du brauchst.

    Man muß viel probieren, von daher kommt das (Praxis, ausprobieren). Nur durch Bücherlesen kommt es nicht (Theorie, hat man 5 Minuten später schon vergessen, was wichtig gewesen wäre).

    Also, in Bezug auf meine C# Programmierung:

    Es funktioniert zunehmend so dies und das. Nicht immer, aber immer öfter.

    Und die Hoffnung stirbt zuletzt 😉

    Pascal



  • pascal2009 schrieb:

    Ich hab ganz nette Grundlagen in Ansi-C. Das hab ich glaube ich ziemlich gut begriffen, von der Denke. Hätte Ansi-C eine GUI, wär ich gar nicht hier.

    Ich will ja nicht Dein Weltbild zerstören, aber rate mal in welcher Sprache das WinApi-Interface geschrieben ist.

    Abgesehen davon: Du kriegst hier Hilfe wie Du bemerkst. Trotzdem reicht es langsam mal mit Deinen Tagebucheinträgen. Das interessiert wirklich niemanden. Bleib beim Fachlichen.

    Grüße



  • hustbaer schrieb:

    Das ist auch genau so. Hängt aber nicht mit der Liste zusammen. Das ist allgemein so wenn man mit Reference Typen arbeitet.

    Allgemein ist das gar nicht so und muß auch nicht so sein.

    Wenn du in C mit malloc(sizeof(irgendwas)) einen Zeiger setzt und dem einen Wert zuweist, dann ist der Speicherplatz des neuen Elements nicht identisch mit dem Speicherplatz des zugewiesenen Wertes. Daß List<T> so arbeitet, hätte mich nicht überrascht, wenn malloc() genauso arbeiten würde.

    Ich will hier aber nicht über AnsiC streiten, sondern in C# dazulernen.

    Und ich finde, dazu sind bisher viele gute Beiträge gekommen.

    Pascal



  • pascal2009 schrieb:

    hustbaer schrieb:

    Das ist auch genau so. Hängt aber nicht mit der Liste zusammen. Das ist allgemein so wenn man mit Reference Typen arbeitet.

    Allgemein ist das gar nicht so und muß auch nicht so sein.

    Wenn du in C mit malloc(sizeof(irgendwas)) einen Zeiger setzt und dem einen Wert zuweist, dann ist der Speicherplatz des neuen Elements nicht identisch mit dem Speicherplatz des zugewiesenen Wertes. Daß List<T> so arbeitet, hätte mich nicht überrascht, wenn malloc() genauso arbeiten würde.

    Ich will hier aber nicht über AnsiC streiten, sondern in C# dazulernen.

    Und ich finde, dazu sind bisher viele gute Beiträge gekommen.

    Pascal

    PS: Nochmal meine Programierung in Ansi-C. Liste aus Datei erzeugen. Da kann man sehen, daß es in Ansi-C ganz anders ist als in List<T>. Es ist formal ähnlich, aber von der Logik völlig anders, weil nirgendwo der Speicherplatz von buffer in die Liste rutscht, sondern die Werte für Buffer auf einen neuen Speicherort kopiert werden (das hat mich ja an List<T> so gewundert, daß die immer in Buffer hängenbleibt):

    // ***************************************** PUBLIC nur die Struktur, nicht die Deklarationen
            struct s_element{
                   struct s_element *next;
                   struct s_element *prev;
                   struct s_bsatz data;
                   };
    
    struct s_element *element_anhaengen(struct s_element *vorgaenger)
    {
        struct s_element *neues;
        neues=malloc(sizeof(struct s_element));
        neues->next=NULL;
        if (vorgaenger==NULL) neues->prev=NULL;
        else {neues->prev=vorgaenger;vorgaenger->next=neues;}
        return neues;
    }
    
    struct s_element *kopiere_datei_in_liste(char *dname)
    {
            struct s_element *listenkopf=NULL;       
            struct s_element *laufzeiger=NULL;
            struct s_bsatz buffer;     
            FILE *bdp;
            bdp=fopen(dname,"rb");
            if (bdp==NULL){meldung("Kann Datei",dname,"nicht oeffnen");return;}
            while (fread(&buffer,sizeof(struct s_bsatz),1,bdp)==1)
            {
               if (listenkopf==NULL){listenkopf=element_anhaengen(listenkopf);laufzeiger=listenkopf;}
               else laufzeiger=element_anhaengen(laufzeiger);
               laufzeiger->data=buffer;
            }                         
          fclose(bdp);  
          return listenkopf;
    }
    


  • Psuedocode:

    ListElement element_anhaengen(ListElement vorgaenger) 
    { 
        ListElement neues; 
        neues=new ListElement(); 
        neues.next=NULL; 
        if (vorgaenger==null) neues.prev=null; 
        else {neues.prev=vorgaenger;vorgaenger.next=neues;} 
        return neues; 
    } 
    
    ListElement kopiere_datei_in_liste(string dname) 
    { 
            ListElement listenkopf=null;       
            ListElement laufzeiger=null; 
            ListData buffer;     
            FileStream bdp = new FileStream(dname, FileMode.Open);
            //if (bdp==NULL){meldung("Kann Datei",dname,"nicht oeffnen");return;} 
            while (/*read struct*/) 
            { 
               if (listenkopf==null){listenkopf=element_anhaengen(listenkopf);laufzeiger=listenkopf;} 
               else laufzeiger=element_anhaengen(laufzeiger); 
               laufzeiger.data=buffer; 
            }                         
          bdp.Close();   
          return listenkopf; 
    }
    

    Macht dann genau das gleiche... 🙄

    Es ist formal ähnlich, aber von der Logik völlig anders, weil nirgendwo der Speicherplatz von buffer in die Liste rutscht, sondern die Werte für Buffer auf einen neuen Speicherort kopiert werden (das hat mich ja an List<T> so gewundert, daß die immer in Buffer hängenbleibt)

    Ehrlich gesagt: Keine Ahnnung was du meinst. 😕
    Wieder das Problem mit Value/Referenz-Typen ?



  • DarkShadow44 schrieb:

    Wieder das Problem mit Value/Referenz-Typen ?

    Ich habe viele Verständnisprobleme mit C#. Nur gerade was Value und Reference betrifft, da hab ich außer dem Umgang mit der Notation überhaupt keine.

    Hilft aber nix, wenn man nicht weiß, wie man die Notation setzen muß um den Compiler dazu zu bewegen, das zu tun, was er soll.

    Es wird ein langer Weg.

    Nett, daß ihr mir hier so behilflich seid.

    Pascal

    Nochmal zu List<T>, was mich daran so irritiert hatte.

    List <T> arbeitet folgendermaßen:

    Ein Element wir mit new erzeugt und mit Daten befüllt

    meineListe.Add führt dann dazu, daß die Liste einen Zeiger auf das Element setzt.

    Würde man das Element verändern (neue Daten aus einer Datei einlesen), und mit

    meineListe.Add hinzufügen, wäre folgendes passiert:

    Der Zeiger von meineListe[0] würde auf das Element zeigen, der Zeiger von meineListe[1] aber auch. Also zeigen alle auf dasselbe Element, egal wie oft man die Funktion .Add aufruft. Wir hätten dann sagen wir 1000 Zeiger auf ein und dasselbe Element erstellt, also das Gegenteil einer Liste, nämlich nur Zeiger auf ein Objekt. Da muß man ja erstmal drauf kommen. Man denkt, die Liste packt die Werte irgendwo in neue SPeicherbereiche, das tut sie aber nicht. Ergo ist das Arbeiten mit dem Befüllen eines Wertebereichs und Zuweisung zur Liste kontraproduktiv bzw. dem Vorgang nicht angemessen.

    Die Notation wie von Mü vorgeschlagen ist dafür optimal

    (1) kontenliste.Add(new CL_Konto(4920, "Telefon"));

    (2) kontenliste.Add(new CL_Konto{ kontonr = 4920, kontobez = "Telefon"});

    Wobei zwischen 1 und 2 der Unterschied besteht, daß der erste Code besser schreibbar ist und der zweite besser lesbar. Ich würde mich aber unbedingt für die 2. Variante entscheiden, da nicht auszuschließen ist, daß sich die Zusammensetzung und die Reihenfolge der Felder im Laufe der Programmierung auch mal ändern könnte und dann hätte man ins Klo gegriffen plus daß der Fehler je nachdem gar nicht so leicht auszumachen wäre.



  • Ein wichtiger Tipp: Hör auf in C zu denken. Man liest ständig so in der Art. In C würde ich das so machen und wie mache ich dann genau das in C#?

    Die Vorgehensweise sollte sein: Ich will Sache X machen und jetzt muss ich schauen wie man Sache X in C# macht _ohne_ den Umweg über C zu gehen. Zur Zeit verrennst Du Dich in teilweise abstrusen Lösungsansätzen weil Du nicht von C loslassen kannst.

    Das ist so wie Menschen die versuche Englisch zu sprechen indem sie den Satz erst in Deutsch formulieren und dann Wort für Wort ins Englische übersetzen. Klappt auch nicht.

    Und wie andere schon sagten, Dein Problem ist nicht C#, sondern OOP-Konzepte. Du würdest in die gleichen Probleme bei jeder anderen Sprache inklusive C++ rennen (C++, nicht unter C++ kompiliertes C)



  • loks schrieb:

    Ein wichtiger Tipp: Hör auf in C zu denken. Man liest ständig so in der Art. In C würde ich das so machen und wie mache ich dann genau das in C#?

    Die Vorgehensweise sollte sein: Ich will Sache X machen und jetzt muss ich schauen wie man Sache X in C# macht _ohne_ den Umweg über C zu gehen. Zur Zeit verrennst Du Dich in teilweise abstrusen Lösungsansätzen weil Du nicht von C loslassen kannst.

    Das ist so wie Menschen die versuche Englisch zu sprechen indem sie den Satz erst in Deutsch formulieren und dann Wort für Wort ins Englische übersetzen. Klappt auch nicht.

    Und wie andere schon sagten, Dein Problem ist nicht C#, sondern OOP-Konzepte. Du würdest in die gleichen Probleme bei jeder anderen Sprache inklusive C++ rennen (C++, nicht unter C++ kompiliertes C)

    Gut erkannt.

    Ich wollte tatsächlich ursprünglich existierende Programmierung 1:1 übertragen. Sozusagen Ansi-C von der Konsole mal eben auf GUI portieren.

    Daß das nicht zielführend ist, hab ich mittlerweile begriffen. Gib mir ein bißchen Zeit.

    Ich arbeite dran. 🤡

    Pascal



  • pascal2009 schrieb:

    [...] die Sichtbarkeit der Methoden und Variablen, das Problem gibt es in C überhaupt so nicht [...]

    Im Grunde siehst Du es genau verkehrt herum. Die Sichtbarkeit des OOP (z.B.) ist in Wirklichkeit eine Lösung für das Problem, das selbige in C fehlt. Lies mal "The Design and Evolution of C++" dann verstehst Du (hoffentlich) das OOP Konzepte aus den Schwächen und Mängeln der C-Sprache entstanden sind und das diese Features keine "Probleme" sind, sondern Lösungen.

    (PS: okok, OOP Konzepte sind auch unabhängig von C entstanden. Ich meinte damit die OOP-Konzepte von z.B. C++ die man ja auch in C# wiederfindet)



  • Der Zeiger von meineListe[0] würde auf das Element zeigen, der Zeiger von meineListe[1] aber auch. Also zeigen alle auf dasselbe Element, egal wie oft man die Funktion .Add aufruft. Wir hätten dann sagen wir 1000 Zeiger auf ein und dasselbe Element erstellt, also das Gegenteil einer Liste, nämlich nur Zeiger auf ein Objekt. Da muß man ja erstmal drauf kommen. Man denkt, die Liste packt die Werte irgendwo in neue SPeicherbereiche, das tut sie aber nicht. Ergo ist das Arbeiten mit dem Befüllen eines Wertebereichs und Zuweisung zur Liste kontraproduktiv bzw. dem Vorgang nicht angemessen.

    Ich versteh das Problem nicht. Wenn du in C einen Pointer hast, per malloc Speicher anforderst und den Speicher wieder und wieder füllst und den Pointer in eine Liste packst hast du das Problem doch auch. 😕

    Wobei zwischen 1 und 2 der Unterschied besteht, daß der erste Code besser schreibbar ist und der zweite besser lesbar. Ich würde mich aber unbedingt für die 2. Variante entscheiden, da nicht auszuschließen ist, daß sich die Zusammensetzung und die Reihenfolge der Felder im Laufe der Programmierung auch mal ändern könnte und dann hätte man ins Klo gegriffen plus daß der Fehler je nachdem gar nicht so leicht auszumachen wäre.

    Ich würde die erste vorziehen. Konstruktoren sind für die Kapselung zuständig.



  • DarkShadow44 schrieb:

    Der Zeiger von meineListe[0] würde auf das Element zeigen, der Zeiger von meineListe[1] aber auch. Also zeigen alle auf dasselbe Element, egal wie oft man die Funktion .Add aufruft. Wir hätten dann sagen wir 1000 Zeiger auf ein und dasselbe Element erstellt, also das Gegenteil einer Liste, nämlich nur Zeiger auf ein Objekt. Da muß man ja erstmal drauf kommen. Man denkt, die Liste packt die Werte irgendwo in neue SPeicherbereiche, das tut sie aber nicht. Ergo ist das Arbeiten mit dem Befüllen eines Wertebereichs und Zuweisung zur Liste kontraproduktiv bzw. dem Vorgang nicht angemessen.

    Ich versteh das Problem nicht. Wenn du in C einen Pointer hast, per malloc Speicher anforderst und den Speicher wieder und wieder füllst und den Pointer in eine Liste packst hast du das Problem doch auch. 😕

    Wobei zwischen 1 und 2 der Unterschied besteht, daß der erste Code besser schreibbar ist und der zweite besser lesbar. Ich würde mich aber unbedingt für die 2. Variante entscheiden, da nicht auszuschließen ist, daß sich die Zusammensetzung und die Reihenfolge der Felder im Laufe der Programmierung auch mal ändern könnte und dann hätte man ins Klo gegriffen plus daß der Fehler je nachdem gar nicht so leicht auszumachen wäre.

    Ich würde die erste vorziehen. Konstruktoren sind für die Kapselung zuständig.

    Also du sprichst da ein wichtiges Problem an:

    Bibliotheksfunktionen wie List<T> sind im allgemeinen selbstgeschriebenen Funktionen vorzuziehen, da nachgewiesenermaßen fehlerfrei.

    Das Problem ist aber, man muß die Funktion auch verstehen, was sie macht, wie sie was macht und welche Seiteneffekte davon ausgehen könnten, das heißt also, nicht nur einfach anwenden, sondern zuvor testen und verstehen. Sonst kommen da Seiteneffekte, die man nicht abschätzen kann, weil man die Funktion nicht wirklich versteht. Es braucht eben seine Zeit. 😋

    Was das zweite angeht, wie man mit Konstrukturen kapselt, ist für mich im Augenblick noch chinesische Geheimwissenschaft. Solange das so ist, lege ich eher Wert auf gut lesbaren Code, den man versteht und auch warten kannn.

    Daß du dich aber in C# bestens auskennst hab ich schon bemerkt an der Schnelligkeit deiner Codierung. Möglicherweise übersiehst du daher die Schwierigkeiten eines Anfängers, sich da reinzufinden.

    Ich baue den Einstieg in C# so auf, daß ich mir Codebeispiele hole, die austeste, und wenn sie funktionieren, die archiviere und mit anderen kombiniere. Dabei kann es durchaus vorkommen, daß ich bestimmte Codeschnippsel nicht verstehe, aber anwende.

    Am Ende sollte dann das Verständnis des Ganzen stehen. Am Anfang kann man das nicht erwarten sondern muß froh sein, wenn man das, was man will, überhaupt erstmal ans Laufen bringt.

    In Ansi-C hab ich vor 3 Jahren eine Fibu geschrieben, die läuft bis heute ohne einen einzigen Programmabsturz, was bei AnsiC ja nicht unbedingt die Norm ist. Zwei Steuererklärungen wurden damit abgegeben. Das Programm hat aber keine GUI.

    Die fehlende GUI ist mein Motiv.

    Die GUI hab ich schon ganz gut im Griff, aber das tiefere Verständnis von C#, bis dahin ist es noch ein langer Weg.

    Pascal


Anmelden zum Antworten