Announcement

Collapse
No announcement yet.

Wie setzte ich eine dynamische Strktur in C# um . . .

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Wie setzte ich eine dynamische Strktur in C# um . . .

    Hallo zusammen,

    also irgendwie stehe ich wohl auf der leitung. Also ich definiere eine Struktur in c++. Da ich nicht weiss wie viele Sätze ich in dieser Struktur ablegen werde, hole ich mir dynamisch Speicher. Das diese Struktur in einer eigenen Klasse hängt, muss dieses Array der Struktur nach aussen getragen werden.

    typedef struct users {
    char Alias[255+1];
    char Lastname[255+1];
    char Firstname[255+1];
    int Profile;
    char LanguageID[10+1];
    char Admin[1+1];
    char Activ[1+1];
    char Deleted[1+1];
    char Hidden[1+1];
    char CreatedAt[23+1];
    char CreatedBy[255+1];
    char ModifiedAt[23+1];
    char ModifiedBy[255+1];
    char DeletedAt[23+1];
    char DeletedBy[255+1];
    } tsUsers, *tpsUsers;

    fUsers = (tpsUsers) calloc(fDBTable-
    memset(fUsers, '\0', sizeof(tsUsers) * fDBTable->RecordCount);

    Dies habe ich so in C++ deniniert. Jetzt die Frage, wie setze ich das in C# um, und wie greife ich auf die einzelnen Werte des Satzes zu, wenn diese Struktur in einer eigenen Klasse gekapselt ist? Für ein Beispiel wäre ich sehr dankbar.

  • #2
    Hallo<P>
    Ich hoffe ich habe Dich korrekt verstanden:

    <PRE>
    // Struktur definieren.
    public struct Users {
    public string Alias;
    public string Lastname;
    // ... etc.
    }

    // Array anlegen.
    Users[] users = new Users[10]
    users[0].Alias = "Ein Alias";
    // ... etc.
    // Oder mit einer Arraylist.
    System.Collections.ArrayList users1 = new System.Collection.ArrayList();
    Users u1 = new Users();
    u1.Alias = "Ein anderer Alias";
    users1.Add(u1);
    string a1 = users1[0].Alias;
    </PRE>

    Warum machst Du keine Klasse für Users?<P>
    Ich bin mir nicht sicher ob Dir das hilft...<P>
    Gruss Simo

    Comment


    • #3
      Hi,

      zuerst mal danke. So weit war ich glaube ihc auch schon. Ich habe eine Klasse geschrieben, die meherer Dinge tut. Unter anderem hat alle User aus einer DB lesen. Jetzt möchte ich mit einem Schlag alle User an mein MainForm übergeben. Mit anderen Worten, ich generiere eine neue Instanz meiner Klasse mit new. Dann gebe ich den Auslöser, alle User zu lesen. Diese User stehen alle in einer Struktur, die ich aus dem Main heraus nur per Schleife auslesen möchte ( for i = 0 . . .).

      Oder denke ich zu kompliziert, denn .NET ist noch ziemlich neu für mich..

      Gruss

      Sasch

      Comment


      • #4
        Oops,

        ein paar Tippfehler sorry, War mal wieder zu schnell mit den Fingern . .

        Comment


        • #5
          hmm wo liegt hier das problem - ich verstehs nicht ganz

          du kannst doch dein klasse in einer collection abspeichern - die kannst du dann beliebig wieder auslesen

          Comment


          • #6
            Tja, wie gesagt, ich fange gerade erst mit c# an.

            Ich habe wie in C++ eine Datei, in der mein Hauptprogramm steht. Jetzt gibt es eine neue Datei in der ich alle Klassen relevanten Programmteile unterbringe. Jetzt connecte ich mich in meiner Klasse mit einer DB und möchte z.B. meine User in eine Struktur innerhalt meiner Klasse abspeichern. Diese Struktur möchte ich jetzt wie in C++ von meinem Hauptprogramme ansprechen. Ich möchte die Struktur für die User nicht als Klasse abbilden, da ich hierfür keinen richtigen Sinn sehe.

            Früher ging das ungefähr so:

            typedef struct users {
            char Alias[255+1];
            char Lastname[255+1];
            char Firstname[255+1];
            char Password[255+1];
            int Profile;
            char LanguageID[10+1];
            char Admin[1+1];
            char Activ[1+1];
            char Deleted[1+1];
            char Hidden[1+1];
            char CreatedAt[23+1];
            char CreatedBy[255+1];
            char ModifiedAt[23+1];
            char ModifiedBy[255+1];
            char DeletedAt[23+1];
            char DeletedBy[255+1];
            } tsUsers, *tpsUsers;

            class TGlbFunctions : public TObject
            {
            private:
            tpsUsers fUsers;
            public:
            __fastcall TGlbFunctions(AnsiString, AnsiString);
            __fastcall ~TGlbFunctions(void);

            void __fastcall GetAllUsers(void);

            __property tpsUsers Users = { read = fUsers };
            };

            Jetzt kommt meine Hauptanwendung:

            TGlbFunctions *Session;

            Session = new TGlbFunctions(ExtractFilePath(ParamStr(0)) + "Database\\Data.mdb", fParam1);

            ShowMessage("Session->Users[idx].Alias");

            usw . . . .

            Vielleicht stehe ich einfach nur auf der Leitung, oder was weiss ich.

            Gruß

            Sasch

            Comment


            • #7
              Hi<P>
              Ich versuche es mal... :-))
              <P>
              <PRE>
              // erbt implizit von System.ValueType !!
              public struct User {
              public string Alias;
              }

              // erbt implizit von System.Object
              public class TGlbFunctions {

              private User[] users = new User[0];

              // Konstruktor
              public TGlbFunctions(string path) {
              }

              // Erzeuge/hole von irgendwoher die User
              // und speichere sie in das users array ab.
              private void FillUsers() {}

              // Mache deine Users per Property
              // zugreifbar.
              public User[] Users {
              get {
              return users;
              }
              }
              }

              // Klasse welche main enthält.
              public class Class1 {

              public static void Main(string[] args) {

              TGlbFunctions session = new TGlbFunctions("C:\Test.mdb");
              string alias = session.Users[0].Alias;
              }
              }
              </PRE>

              -> User ist als struct implemetiert, d.h. es ist ein ValueType, was bedeuted, wenn Du z.B. ein User aus deinem Array holst, kriegst Du KEINE Referenz, sondern eine Kopie!!

              Gruss Simo

              Comment


              • #8
                Hallo und danke erstmal.

                So weit habe ich das verstanden. Aber . . . liegt die struktur innerhalb des namespaces oder nicht. Wieso definierst Du:

                private User[] users = new User[0];

                Habe ich damit nicht 0 Sätze? Da es scheinbar keiner richtigen Counter der Sätze innerhalb des OleDbDataReader's gibt, wie erweitere ich das Array um die Anzahl user? Denn wenn ich innerhalb der While Schleife ein new auf User mache, "knallt es ziemlich" <<FEHLER>>.

                Gruß

                Sasch

                Comment


                • #9
                  Hi
                  <P>
                  Ja, die Strktur liegt innerhalb des Namespaces (in welchem auch immer). Ist Aber nicht in der Klasse TGlbFunctions, dann WÄRE es eine "nested class/struct".
                  <P><P>
                  private User[] users = new User[0];
                  <P>
                  Das habe ich gemacht, dass wenn jemand z.B. session.Users.Length aufruft, es keine NullReferenceException gibt.
                  <P><P>
                  Beim füllen des Arrays (users), erzeugst Du dann ein neues Array, mit der richtigen Anzahl User.
                  <P><P>
                  Z.B. könntest Du zuerst Datensatz für Datensatz in eine ArrayList einlesen und am Schluss ein Users Array daraus erzeugen.
                  <P>
                  Gruss Simo

                  Comment


                  • #10
                    Danke Dir.

                    Aber irgendwie ist diese Art der Programmierung mir noch etwas fremd. Leider muss ich das, was Du mir netterweise geschrieben hast auch verinnerlichen, damit ich es verstehe.

                    Denn nur abschreiben finde ich nicht gut, man sollte schon wissen was man da tut, oder? Deshalb möchte ich Dich bitten, nur wenn die Lust und Zeit hast, mir vielleicht ein kleines Beispiel zu „posten“. Denn leider probiere ich hier rum und komme auf keinen wirklich grünen Zweig. Sorry das ich dich so nerve, aber im Moment stehe ich einfach vor einer riesigen Wand, und weder links noch rechts ein kleiner Lichtblick.

                    Solltest Du keine Zeit oder Lust haben, so gib mir bitte auch kurz Bescheid, damit ich mein „Glück“ weiter versuchen kann, ok?

                    Tausend Danke schon mal bis hierhin

                    Sasch

                    Comment


                    • #11
                      Hi<P>
                      Vielleicht kaufst Du Dir besser ein Buch, da wird alles Schritt für Schritt erklärt und Du lernst die Framework Klassen kennen.
                      <P>
                      Gruss Simo

                      Comment


                      • #12
                        Hi,

                        tja, ein Buch habe ich ja, aber irgendwie wird da ein solcher Fall nicht wirklich drin beschrieben. Aber ich habe auch noch andere Bücher über das Framework. Aber in Kombination all dieser Dinge suche ich scheinbar in allen Büchern vergebens. Deshalb habe ich mich ja auch an dieses Forum gewendet, um hier eine Lösung zu finden. Das jetzt hier auf Bücher verwiesen wird, erstaunt mich doch jetzt ziemlich stark. Aber warum sollte es in diesem Forum anders laufen als in Anderen . . .

                        Trotzdem herzlich Dank

                        Gruß

                        Sasch

                        Comment


                        • #13
                          Hmmm
                          <P>
                          Nunja, mit der vorangegangenen Bemerkung fällts mir sowiso schwer, etwas hilfreiches zu posten

                          Comment


                          • #14
                            Hi nochmal,

                            ich weiss zwar nicht was jetzt an der letzten Bemerkung auszusetzen ist, aber wenn Du der Meinung sein solltest, das bei mir ein negativer Hintergedanke dahinter steckt, so muss und werden ich mich natürlich in aller Höfflichkeit bei Dir Entschuldigen. Vielleicht, und das will ich garnicht ausschließen, bin ich etwas gefrustet, auf dem doch jetzt schon recht langen Weg nach einer Lösung. Ich hoffe Du nimmst meine Entschuldigung an, und man kann wieder auf normalen Niveau miteinanderen "schreibe".

                            Du erwähntest, das ich mir ein Buch kaufen soll. Tja, welches denn? Vielleicht habe ich zwar viele Bücher über das Thema, aber vielleicht genau die falschen.

                            Also vielleicht zur Info:

                            Ich habe:

                            Go gto c#
                            C# Cookbook
                            Crashkurs.NET für Borland

                            Dann gab es mal eine kleine Reihe von Online Books.

                            Wäre es möglich, wenn Du mir eines Deiner Bücher empfehlen könntest, damit ich einer Lösung etwas näher komme.

                            Und sorry nochmal für das letzte Statement, wenn dieses wirklich so falsch bei Dir angekommen sein sollte.

                            Gruß

                            Sasch

                            Comment


                            • #15
                              Hallo,

                              &gt;..Crashkurs.NET ...

                              das muss belohnt werden ;-)

                              Generell fängt eine Antwort bei der Frage an, welche Aufgabe umgesetzt werden soll? Es wird oftmals nicht sinnvoll sein, denn "alten" C++ Weg im Maßstab 1:1 nachzubauen.

                              &gt;fUsers = (tpsUsers) calloc(fDBTable- memset(fUsers, '\0', sizeof(tsUsers) * fDBTable->RecordCount);

                              Bei dieser Zeile fällt mir sofort die <b>DataTable</b>-Klasse aus dem .NET Framework ein. Diese Klasse bringt alles Notwendige mit, um zur Laufzeit eine eigene Feldstruktur ("Daten-Tabelle") anzulegen und dann über den extrem bequemen objektorientierten Weg mit Daten zu füllen. Das könnte zum Beispiel so aussehen:
                              <pre>
                              <b>private</b> DataTable aNewDataTable;
                              <br>
                              <b>private</b> <b>void</b> button1_Click(<b>object</b> sender, System.EventArgs e)
                              {
                              <font color="#003399"><i>// neue DataTable erzeugen</i></font>
                              aNewDataTable = <b>new</b> DataTable();
                              DataColumn aPKCol;
                              <b>Object</b>[] aRowData;
                              aPKCol = aNewDataTable.Columns.Add(<font color="#9933CC">&quot;RecID&quot;</font>, <b>typeof</b>(Int32));
                              aPKCol.AutoIncrement = <b>true</b>;
                              aPKCol.AutoIncrementSeed = 1000;
                              aPKCol.AutoIncrementStep = 5;
                              aNewDataTable.Columns.Add(<font color="#9933CC">&quot;Nachname&quot;</font>, <b>typeof</b>(<b>String</b>));
                              aNewDataTable.Columns.Add(<font color="#9933CC">&quot;Vorname&quot;</font>, <b>typeof</b>(<b>String</b>));
                              aNewDataTable.Columns.Add(<font color="#9933CC">&quot;Alter&quot;</font>, <b>typeof</b>(Int32));
                              aNewDataTable.PrimaryKey = <b>new</b> DataColumn[] {aPKCol};
                              <font color="#003399"><i>// Datensatz eintragen</i></font>
                              aRowData = <b>new</b> <b>Object</b>[] {<b>null</b>, <font color="#9933CC">&quot;Kosch&quot;</font>, <font color="#9933CC">&quot;Andreas&quot;</font>, 40};
                              aNewDataTable.LoadDataRow(aRowData, <b>true</b>);
                              aRowData = <b>new</b> <b>Object</b>[] {<b>null</b>, <font color="#9933CC">&quot;Mustermann&quot;</font>, <font color="#9933CC">&quot;Manfred&quot;</font>, 55};
                              aNewDataTable.LoadDataRow(aRowData, <b>true</b>);
                              aRowData = <b>new</b> <b>Object</b>[] {<b>null</b>, <font color="#9933CC">&quot;Regel&quot;</font>, <font color="#9933CC">&quot;Wolfgang&quot;</font>, 51};
                              aNewDataTable.LoadDataRow(aRowData, <b>true</b>);
                              <font color="#003399"><i>// neue Spalte hinzufügen, der Wert vom Programm gesetzt wird</i></font>
                              DataColumn aExpCol = <b>new</b> DataColumn();
                              aExpCol.ColumnName = <font color="#9933CC">&quot;Berechnet&quot;</font>;
                              aExpCol.DataType = <b>typeof</b>(<b>Decimal</b>);
                              aNewDataTable.Columns.Add(aExpCol);
                              <font color="#003399"><i>// anzeigen</i></font>
                              dataGrid1.DataSource = aNewDataTable;
                              }
                              </pre>
                              <pre>
                              <font color="#003399"><i>// Version 1: Alle Datensätze der DataTable selbst initialisieren</i></font>
                              <br>
                              <b>private</b> <b>void</b> button2_Click(<b>object</b> sender, System.EventArgs e)
                              {
                              <b>for</b> (<b>int</b> i = 0; i &lt;= aNewDataTable.Rows.Count - 1; i++)
                              aNewDataTable.Rows[i][<font color="#9933CC">&quot;Berechnet&quot;</font>] = Convert.ToInt32(textBox1.Text) +
                              (<b>int</b>)aNewDataTable.Rows[i][<font color="#9933CC">&quot;Alter&quot;</font>];
                              }
                              <br>
                              <font color="#003399"><i>// Version 2: Expression nutzt Eingabe im TextBox-Control</i></font>
                              <br>
                              <b>private</b> <b>void</b> button3_Click(<b>object</b> sender, System.EventArgs e)
                              {
                              <b>int</b> iOffset = Convert.ToInt32(textBox1.Text);
                              <b>string</b> sExpr = <font color="#9933CC">&quot;Alter + &quot;</font> + iOffset;
                              <font color="#003399"><i>// neue berechnete Spalte hinzufügen</i></font>
                              DataColumn aExpCol = <b>new</b> DataColumn();
                              aExpCol.ColumnName = <font color="#9933CC">&quot;Berechnet2&quot;</font>;
                              aExpCol.DataType = <b>typeof</b>(<b>Decimal</b>);
                              aExpCol.Expression = sExpr;
                              aNewDataTable.Columns.Add(aExpCol);
                              }
                              </pre>
                              Alternativ könnte man die Datenstruktur auch innerhalb von Visual Studio .NET 2003 über den <i>XML Schema Designer</i> visuell zusammenklicken und als XSD-Datei speichern, um daraus automatisch die Hilfsklasse für das typisierte DataSet zu machen (in diesem Fall erledigt VS.NET die ganze Arbeit, wir binden nur die automatisch generierte Hilfsklasse ein, um typsicher auf die Datenstruktur zugreifen zu können).

                              Sind die Daten erst einmal in der DataTable-Instanz, können diese universell über die Methoden der DataTable-Klasse weiterverarbeitet werden. Damit entfällt die Notwendigkeit, mühsam etwas eigenes Zusammenstricken zu müssen.

                              &gt;Ich möchte die Struktur für die User nicht als Klasse abbilden, <br>
                              &gt;da ich hierfür keinen richtigen Sinn sehe.

                              Das Problem bei diesem Satz besteht darin, dass in .NET so ziemlich alles eine Klasse ist - vom Integer angefangen :-)<br>
                              Dies bedeutet, man muss eine gute Begründung an der Hand haben, wenn etwas <b>nicht</b> als Klasse implementiert werden soll bzw. wenn eine bereits vorhandene Klasse aus dem .NET Framework nicht verwendet werden soll.

                              Ab Beispiel der Structure (structs) könnte die Begründung sein, dass aus Performance-Gründen eine explizite Speicherung der Daten als Values Types auf dem Stack (oder Inline) unbedingt notwendig ist. Dies wird aber nur in seltenen Fällen ein wirklicher Grund sein - so dass in der Regel die Klasse der Normalfall ist.

                              &#10

                              Comment

                              Working...
                              X