none
Klassen mit Array einer anderen Klasse (Zugriff nicht möglich) RRS feed

  • Frage

  • Hallo zusammen, ich habe die u.a. Klasse erstellt die ein Array einer anderen Klasse enthält. (alles exemplarisch dargestellt!)

     

    public class Bestellungen
    {
    private string Artikel{ get; set; }
    }
    //Hauptklasse
    public class Kunden
    {
    private string Name { get; set; }
    private int ID { get; set; }
    //Mein Array zur Klasse oben
    public Bestellungen[] BestellItem;
    public Kunden() {}
    }
    //Da ich mehrere Kunden haben kann erstelle ich eine Liste
    List<Kunden> Customer = new List<Kunden>();
    //Ich fülle Sie mal exemplarisch mit 10 dummy Datensätzen
    for (int i = 0; i < 10; i++)
    {
    Customer[i].Name = "Kunde " + i.ToString();
    Customer[i].ID = i;
    //So Wie befülle ich nun das Array in der Klasse?
    //Da ich das noch aus C/C++ Zeiten kenne würde ich es so
    //machen...
     // Array mit 5 Dummy Items füllen
    for (int x = 0; x < 5; x++)
    {
    Customer[i].BetsellItem[d].Artikel = "10 Liter Milch";
    }

    //Ich sollte danach nun 10 Dummy Kunden mit je 5 Bestellungen //haben oder?
    }

     

    Ich habe nun folgende Probleme/Verständnisfragen:

    1. Ist die Klassenerstellung so überhaupt korrekt oder mache ich da schon etwas falsch?

    2. Wie initialisiere ich das Array innerhalb der Klasse korrekt, so das ich wie in meinem exemplarischen Beispiel 10 Kunden mit je 5 Bestellungen bekomme.

    3. Wie kann ich die Daten nach der Initialisierunge wieder anzeigen lassen? Ich würde das auch wieder mit for schleifen machen oder aber so:

     

    foreach(var k in Customer)
    {
     Console.WriteLine("Kunde {0}", k.Name);
     
     foreach(var b in Customer.BestellItem)
     {
     Console.WriteLine("\n"BetsellItem: {0}", b.Artikel);
     }
    }

     


    Mittwoch, 4. August 2010 22:01

Antworten

  • Hallo S.,

    eine Beispiel-Implementierung:

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    
    namespace WinCollectFrage
    {
     public partial class Form1 : Form
     {
      public Form1()
      {
       InitializeComponent();
       DummyKundenErstellen();
       DummyKundenAnzeigen();
      }
    
      private void DummyKundenAnzeigen()
      {
       foreach (var k in kunden)
       {
        Console.WriteLine("\nKunde: {0}", k.Name);
        foreach (var b in k.Bestellungen)
         Console.WriteLine("  Bestellung: {0}", b.Artikel);
       }
      }
    
      List<Kunde> kunden = new List<Kunde>();
    
      public class Bestellung
      {
       public string Artikel { get; set; }
      }
    
      public class Kunde
      {
       public string Name { get; set; }
       public int ID { get; set; }
    
       public Bestellung[] Bestellungen;
      }
    
      private void DummyKundenErstellen()
      {
       int anzahlDummyKunden = 10;
       int anzahlDummyBestellungen = 5;
    
       for (int i = 0; i < anzahlDummyKunden; i++)
       {
        Kunde kunde = new Kunde();
        kunde.Name = "Kunde " + i.ToString();
        kunde.ID = i;
        kunde.Bestellungen = new Bestellung[anzahlDummyBestellungen];
    
        for (int x = 0; x < anzahlDummyBestellungen; x++)
         kunde.Bestellungen[x] = new Bestellung
         {
          Artikel = x + anzahlDummyBestellungen
          + " Liter Milch"
         };
        kunden.Add(kunde);
       }
      }
     }
    }
    
    

     

     


    ciao Frank
    Donnerstag, 5. August 2010 06:12
  • Hallo,

    auch in C++ würde man heute einen STL vector verwenden,
    als direkt ein Array nach aussen zu reichen.

    Auch .NET ist gut mit Auflistungen ausgestattet. Und die nehmen einem solchen Dinge
    wie das Verwalten der richtigen Größe beim Wachsen (wie beim Schrumpfen) ab.
    Bei einem Array müsstest Du Dich selbst darum kümmern.

    Was bei öffentlichen Klassen schnell zu viel Aufwand und am Ende zu schwer
    kontrollierbaren Strukturen (inkl. Fehlern) führen kann.

    Verwenden kannst Du für den Anfang List<T> womit die grundlegenden Funktionen
    vorhanden sind. Allerdings werden dadurch auch viele Erweiterungsmethoden sichtbar,
    so dass man für öffentliche Klassen häufig auf Collection<T> zurückgreift.

    Eine einfache Implementation nach dem Muster wäre:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace ElmarBoye.Samples.Code
    {
      public class Bestellung
      {
        public string Artikel { get; set; }
    
        public override string ToString()
        {
          return "[Bestellung: " + this.Artikel + "]";
        }
      }
    
      public class Kunde
      {
        public Kunde() { }
    
        // Einfacher für die Anlage 
        public Kunde(int id, string name)
        {
          this.ID = id;
          this.Name = name;
        }
    
        public string Name { get; set; }
        public int ID { get; set; }
    
        // Alternativ IList<Bestellungen>
        private List<Bestellung> _bestellungen = new List<Bestellung>();
    
        public List<Bestellung> Bestellungen
        {
          get
          {
            return this._bestellungen;
          }
        }
    
        public override string ToString()
        {
          var builder = new StringBuilder();
          
          builder.AppendFormat("[Kunde {0}:\n", this.Name);
          foreach (var bestellung in Bestellungen)
          {
            builder.AppendFormat("\t{0}\n", bestellung);
    
          }
          builder.AppendLine("]");
          return builder.ToString();
        }
      }
    
      // Anstatt List<T> auch System.Collections.ObjectModell.Collection<T>
      public class Kunden : System.Collections.Generic.List<Kunde>
      {
        public static Kunden Create()
        {
          // Da ich mehrere Kunden haben kann erstelle ich eine Liste
          var kunden = new Kunden();
    
          //Ich fülle Sie mal exemplarisch mit 10 dummy Datensätzen
          for (int i = 0; i < 10; i++)
          {
            var kunde = new Kunde(i, "Kunde " + i.ToString());
            for (int x = 0; x < 5; x++)
            {
              // Alternativ: Konstruktor mit Parametern wie bei Kunde
              kunde.Bestellungen.Add(
                new Bestellung() { Artikel = x.ToString() + " Liter Milch" });
            }
            
            // und anfügen..
            kunden.Add(kunde);
          }
          return kunden;
        }
    
        public override string ToString()
        {
          var builder = new StringBuilder();
    
          foreach (var kunde in this)
            builder.AppendLine(kunde.ToString());
          return builder.ToString();
        }
      }
    }
    

    Und zum Angucken:

          var kunden = Kunden.Create();
          Console.WriteLine(kunden.ToString());
    
    
    Wobei ich die Instanzklasen im Singular benannt habe,
    denn damit kann man die zugehörige Auflistung als Plural schreiben,
    was sich insgesamt natürlicher liest.

    Für die Bestellung würde man in der Praxis eine Auflistung wie bei Kunde(n) verwenden,
    da eine reale Bestellung doch mehr als eine string Artikel Eigenschaft enthält.

    Gruß Elmar

    Donnerstag, 5. August 2010 08:44
  • Hallo, velen Dank! Die beiden Beispiele haben mir weitergeholfen, ich habe es gestern auch über List<T>(); gelöst, statt über das Array[]. Für mich fühlte sich das intuitiver an.
    Donnerstag, 5. August 2010 18:32

Alle Antworten

  • Hallo S.,

    eine Beispiel-Implementierung:

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    
    namespace WinCollectFrage
    {
     public partial class Form1 : Form
     {
      public Form1()
      {
       InitializeComponent();
       DummyKundenErstellen();
       DummyKundenAnzeigen();
      }
    
      private void DummyKundenAnzeigen()
      {
       foreach (var k in kunden)
       {
        Console.WriteLine("\nKunde: {0}", k.Name);
        foreach (var b in k.Bestellungen)
         Console.WriteLine("  Bestellung: {0}", b.Artikel);
       }
      }
    
      List<Kunde> kunden = new List<Kunde>();
    
      public class Bestellung
      {
       public string Artikel { get; set; }
      }
    
      public class Kunde
      {
       public string Name { get; set; }
       public int ID { get; set; }
    
       public Bestellung[] Bestellungen;
      }
    
      private void DummyKundenErstellen()
      {
       int anzahlDummyKunden = 10;
       int anzahlDummyBestellungen = 5;
    
       for (int i = 0; i < anzahlDummyKunden; i++)
       {
        Kunde kunde = new Kunde();
        kunde.Name = "Kunde " + i.ToString();
        kunde.ID = i;
        kunde.Bestellungen = new Bestellung[anzahlDummyBestellungen];
    
        for (int x = 0; x < anzahlDummyBestellungen; x++)
         kunde.Bestellungen[x] = new Bestellung
         {
          Artikel = x + anzahlDummyBestellungen
          + " Liter Milch"
         };
        kunden.Add(kunde);
       }
      }
     }
    }
    
    

     

     


    ciao Frank
    Donnerstag, 5. August 2010 06:12
  • Hallo,

    auch in C++ würde man heute einen STL vector verwenden,
    als direkt ein Array nach aussen zu reichen.

    Auch .NET ist gut mit Auflistungen ausgestattet. Und die nehmen einem solchen Dinge
    wie das Verwalten der richtigen Größe beim Wachsen (wie beim Schrumpfen) ab.
    Bei einem Array müsstest Du Dich selbst darum kümmern.

    Was bei öffentlichen Klassen schnell zu viel Aufwand und am Ende zu schwer
    kontrollierbaren Strukturen (inkl. Fehlern) führen kann.

    Verwenden kannst Du für den Anfang List<T> womit die grundlegenden Funktionen
    vorhanden sind. Allerdings werden dadurch auch viele Erweiterungsmethoden sichtbar,
    so dass man für öffentliche Klassen häufig auf Collection<T> zurückgreift.

    Eine einfache Implementation nach dem Muster wäre:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace ElmarBoye.Samples.Code
    {
      public class Bestellung
      {
        public string Artikel { get; set; }
    
        public override string ToString()
        {
          return "[Bestellung: " + this.Artikel + "]";
        }
      }
    
      public class Kunde
      {
        public Kunde() { }
    
        // Einfacher für die Anlage 
        public Kunde(int id, string name)
        {
          this.ID = id;
          this.Name = name;
        }
    
        public string Name { get; set; }
        public int ID { get; set; }
    
        // Alternativ IList<Bestellungen>
        private List<Bestellung> _bestellungen = new List<Bestellung>();
    
        public List<Bestellung> Bestellungen
        {
          get
          {
            return this._bestellungen;
          }
        }
    
        public override string ToString()
        {
          var builder = new StringBuilder();
          
          builder.AppendFormat("[Kunde {0}:\n", this.Name);
          foreach (var bestellung in Bestellungen)
          {
            builder.AppendFormat("\t{0}\n", bestellung);
    
          }
          builder.AppendLine("]");
          return builder.ToString();
        }
      }
    
      // Anstatt List<T> auch System.Collections.ObjectModell.Collection<T>
      public class Kunden : System.Collections.Generic.List<Kunde>
      {
        public static Kunden Create()
        {
          // Da ich mehrere Kunden haben kann erstelle ich eine Liste
          var kunden = new Kunden();
    
          //Ich fülle Sie mal exemplarisch mit 10 dummy Datensätzen
          for (int i = 0; i < 10; i++)
          {
            var kunde = new Kunde(i, "Kunde " + i.ToString());
            for (int x = 0; x < 5; x++)
            {
              // Alternativ: Konstruktor mit Parametern wie bei Kunde
              kunde.Bestellungen.Add(
                new Bestellung() { Artikel = x.ToString() + " Liter Milch" });
            }
            
            // und anfügen..
            kunden.Add(kunde);
          }
          return kunden;
        }
    
        public override string ToString()
        {
          var builder = new StringBuilder();
    
          foreach (var kunde in this)
            builder.AppendLine(kunde.ToString());
          return builder.ToString();
        }
      }
    }
    

    Und zum Angucken:

          var kunden = Kunden.Create();
          Console.WriteLine(kunden.ToString());
    
    
    Wobei ich die Instanzklasen im Singular benannt habe,
    denn damit kann man die zugehörige Auflistung als Plural schreiben,
    was sich insgesamt natürlicher liest.

    Für die Bestellung würde man in der Praxis eine Auflistung wie bei Kunde(n) verwenden,
    da eine reale Bestellung doch mehr als eine string Artikel Eigenschaft enthält.

    Gruß Elmar

    Donnerstag, 5. August 2010 08:44
  • Hallo Elmar,

    Du schriebst:
           public Kunde(int id, string name)

    es nur eine Kleinigkeit, aber in diesem Fall besser ist:
           public Kunde(int id, string name) : this()

    Der Grund ist, dass (ggf. spätere) Änderungen im parameterlosen Konstruktor natürlich auch in anderen Konstruktoren ausgeführt werden sollten. Nur deswegen, weil das sicher auch für andere lehrreich ist.
    Ansonsten ist Deine Implementierung ja ähnlich zu meiner - deine finde ich aber auch ok.
    Später wird man vielleicht eher über das EF arbeiten.


    ciao Frank
    Donnerstag, 5. August 2010 13:28
  • Hallo, velen Dank! Die beiden Beispiele haben mir weitergeholfen, ich habe es gestern auch über List<T>(); gelöst, statt über das Array[]. Für mich fühlte sich das intuitiver an.
    Donnerstag, 5. August 2010 18:32
  • Hallo S.,

             > Hallo, velen Dank! Die beiden Beispiele haben mir weitergeholfen

    ah, schön.


             > ich habe es gestern auch über List<T>(); gelöst, statt über das Array[].

    das ist auch gut. Es ist oft umständlich mit Array[], wie Du auch in meinem Beispiel dazu siehst, was ich aber nur so implementiert habe, weil es von Dir eine Anforderung war. Ich würde auch List<T> nehmen.
    In Business-Objekten wird ggf. auch mal leichtgewichtigere Listen-Klassen benutzt. Allerdings fehlen einem dann auch ggf. Methoden, was sorgfältig abzuwägen ist.

    Gut, dann können wir diese Frage abschliessen denke ich.


    ciao Frank
    Freitag, 6. August 2010 05:49