Laden...

Grundsatzfrage zur Übergabe von Feldern bzw. Objekten zwischen 2 Klassen

Erstellt von SaFl vor 8 Jahren Letzter Beitrag vor 8 Jahren 1.594 Views
S
SaFl Themenstarter:in
16 Beiträge seit 2015
vor 8 Jahren
Grundsatzfrage zur Übergabe von Feldern bzw. Objekten zwischen 2 Klassen

Erstmal eine freundliches Hallo in die Runde. Dies ist mein erster Beitrag und ich hoffe Ihr könnt mir die nötigen Anregungen geben.

Ich bin recht neu in C# und begreife so langsam die Zusammenhänge der OOP. Programmiererfahrung habe ich allerdings schon aus dem Webbereich (php,javascript usw.). Demnach fällt es mir eigentlich recht leicht, eine Lösung zu finden. Allerdings in diesem Fall, bin ich wahrscheinlich auf dem Holzweg.

Nehmen wir an, ich habe ein Formular. Auf diesem befindet sich eine ListView. Nun möchte ich, dass wenn die Form sich öffnet, dass eine Methode einer Klasse aufgerufen wird.
Diese Methode liest eine XML Datei aus (Es können mehrere Hundert Zeilen sein). Das Ergebnis dieser "Auslesung" soll nun zurückgegeben werden.

Mein Problem: Ich weiß nicht so recht, in welcher Form ich es am sinnvollsten mache.
Erst habe ich gedacht, nen Array mit allen Daten. Geht nicht, da die Anzahl unbekannt ist. Dann habe ich List<t> ausprobiert. Damit es "Mehrdimensional" wird, habe ich die Datensätze in ein Object mit den entsprechenden Feldern gesteckt. Die Rückgabe der List funktionierte, allerdings konnte ich die Objekte nicht extrahieren, bzw. darauf zugreifen. Das Ergebnis war immer classe.objekttyp. Nun bin ich beim DataSet angekommen. Mein plan: Es manuell zu befüllen, übergeben und dort per schleife auslesen um die ListView zu füllen.

Nun meine Frage, welchen Ansatz würdet ihr vorschlagen, um mein Problem zu lösen? Vielleicht auch einen ganz anderen?

Vielen Dank schonmal

Thomas

C
2.121 Beiträge seit 2010
vor 8 Jahren

List<T> ist schon ein guter Ansatz. DataSet ist viel zu aufwendig.

Wie greifst du darauf zu? Was bedeutet classe.objektyp? Wenn du eine typisierte Liste (d.h. mit <T>) verwendest solltest du auch auf alles von T zugreifen können.

16.807 Beiträge seit 2008
vor 8 Jahren

Beachte den Unterschied von Felder und Eigenschaften in C#.
Felder sollten private sein und sind daher für den Datenaustausch nicht geeignet.

Eine generelle Antwort gibt es bei so einer Frage kaum.
Man kann Daten zwischen zwei Klassen übergeben so viele Wege wie es nach Rom gibt.

I.d.R. bietet sich aber immer eine Klassenstruktur an, die genau das abbildet, was Du hast.
Wenn Du eine XML hast, dann hast Du eigentlich für gewöhnlich eine Objektsturktur, die sich mit Collections und Properties problemlos abbilden lässt.

S
SaFl Themenstarter:in
16 Beiträge seit 2015
vor 8 Jahren

Okay, also wenn es um List geht.... also ich habe folgendes:


class Mediathek {
        XmlDocument xdoc = new XmlDocument();
        public List<Song> mediathekAuslesen(){
            List<Song> songs = new List<Song>();
            xdoc.Load("media.xml");
            foreach (XmlNode mp3 in xdoc.SelectNodes("songs/ *")) {
                Song song = new Song(mp3["title"].InnerText, mp3["artist"].InnerText, mp3["album"].InnerText, mp3["duration"].InnerText, mp3["genre"].InnerText, mp3["path"].InnerText, mp3["year"].InnerText);
                songs.Add(song);
            }
            return songs;
        }
    }

class Song {
        string title, artist, album, duration, genre, path;
        string year;

        public Song(string title, string artist, string album, string duration, string genre, string path, string year) {
            this.title = title;
            this.artist = artist;
            this.album = album;
            this.duration = duration;
            this.genre = genre;
            this.path = path;
            this.year = year;
        }
    }

Ich möchte nun einfach in der Klasse Form1


      Mediathek mediathek = new Mediathek();
      List<Song> mediaReturn = mediathek.mediathekAuslesen();

Die Liste empfangen und in der ListView anzeigen.

Wenn ich dann direkt darauf zugreife mit index [0] gibt er tMusic.Song aus. Aber wie kann ich nun auf die einzelnen Felder zugreifen?

Edit: Habe gerade festgestellt, dass die Felder private sind, dann kann ich ja auch nicht darauf zugreifen. Wäre es in diesem Fall ratsam, diese public zu machen?

@Abt, das ist mir schon bewusst, für mich war die Frage auch eher nach einem Lösungsansatz, den ihr vorschlagen würdet, auf Grund eurer Erfahrung... 🙂

16.807 Beiträge seit 2008
vor 8 Jahren

Wie gesagt, Felder sind niemals public.
Ergo bleibt nur die Wahl, dass Du - wie ebenfalls schon gesagt - Properties nimmst.
Das hat auch OOP-Gründe.

S
SaFl Themenstarter:in
16 Beiträge seit 2015
vor 8 Jahren

Dann danke erstmal an dieser Stelle. Ich werde mir das mit den Properties nochmal in Ruhe anschauen. Dann erstmal einen schönen Abend

I
45 Beiträge seit 2012
vor 8 Jahren

Da muß ich doch mal dazwischenfragen:
Wieso "sind Arrays nie public" ?
Aus Tradition ? Gibts da gewichtige Gründe, eine derart wichtige Datenstruktur (für Naturwissenschaftler z. Bsp) private zu machen ?
Und wie sieht dann die Übergabe zwischen Klassen aus ?
Ich höre...

16.807 Beiträge seit 2008
vor 8 Jahren

Wieso "sind Arrays nie public" ?

Niemand hat von Arrays gesprochen. Ich habe gesagt:

Felder sind niemals public.

Und in C# sind Felder keine Arrays; das ist in Java so.

Das ist ein Feld:

private String _fieldName;

Das eine Eigenschaft:

public String PropertyName { get; set; }

Und dieses Konstrukt gibt es in Java überhaupt nicht.

Ich höre...

kommt in einem Forum, bei dem man Hilfe erwartet, verdammt arrogant und unpassend rüber.

1.029 Beiträge seit 2010
vor 8 Jahren

Hi,

noch als Zusatz - Felder könnten public sein - macht man allerdings nicht, da man Eigenschaften wie Abt diese geschrieben hat auch mit Blick auf die Zukunft besser wirklich verwenden sollte.

Das hat einen recht einfachen Hintergrund:

public String PropertyName { get; set; }

Ist nur die Kurzform für:


private string _fieldName;
public string PropertyName
{
get {return _fieldName;}
set {_fieldName=value;}
}

Und wie man an der langen Form sieht - sind get/set Methoden, die auch mehr wie dort oben machen können.

Beispiel für get: Es kann auch sein, dass es sich um eine berechnete Eigenschaft handelt - diese Berechnung kann man dann direkt bei get durchführen/aufrufen.
Beispiel für set: Dein Programm verlässt sich darauf, dass dort richtige Werte gespeichert werden? Kein Thema - denn unter set kann man auch eine Prüfung eventuell zugewiesener Werte vornehmen.

Und auch wenn man denkt, dass man es nicht braucht - ist es gut es zu haben. Der Aufwand ist mittlerweile so klein geworden - kostet nichts mehr - verschafft aber viele Vorteile.

LG

16.807 Beiträge seit 2008
vor 8 Jahren

Das sind einfach grundlegende Dinge aufgrund von OOP.

So können Felder zB nicht in Interfaces deklariert sein, sondern nur Eigenschaften.
Ein Feld gibt immer das gleiche Ergebnis zurück, was zB bei DateTime.Now ziemlich unpraktisch wäre. Dann das Thema Zugriffsicherheit, dass Eigenschaften nur ein Setter haben könnten oder eben das Thema Exceptions...

Felder haben auch Vorteile; aber nicht bei der Aufgabe Klassen"werte" nach _außen _bereit zu stellen.

3.170 Beiträge seit 2006
vor 8 Jahren

Hallo,

ganz sicher ist es nicht das Schlechteste, sich diesbezüglich an die Field Design-Guidelines von Microsoft zu halten - die übrigens ziemlich genau dem entsprechen, was Abt un Taipi88 sagen.

Es werden lediglich 2 Ausnahmen von dieser Regel gemacht, und die betreffen const und static readonly Felder.

DO use constant fields for constants that will never change.
The compiler burns the values of const fields directly into calling code. Therefore, const values can never be changed without the risk of breaking compatibility.

DO use public static readonly fields for predefined object instances.
If there are predefined instances of the type, declare them as public read-only static fields of the type itself.

Wichtig dabei ist aber, zu beachten, was da auch noch steht:

DO NOT assign instances of mutable types to readonly fields.

Ein Beispiel für solche Ausnahmen wäre etwa folgendes (vorausgesetzt struct Angle ist immutable implementiert):

public struct Angle
{
    // unveränderliche!! Konstanten
    public const double DegreesInRightAngle = 90.0;
    public const double DegreesInStraightAngle = 180.0;
    public const double DegreesInFullTurn = 360.0;

    // vordefinierte Instanzen
    public static readonly Angle RightAngle = Angle.FromDegrees(DegreesInRightAngle);
    public static readonly Angle StraightAngle = Angle.FromDegrees(DegreesInStraightAngle);
    public static readonly Angle FullTurn = Angle.FromDegrees(DegreesInFullTurn);

    // weitere Implementierung der struct
    ...
}

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca