Laden...

In welcher Art und Weise stelle ich Daten und Listen zur Verfügung (List<T>, BindingList<T>, ...)

Erstellt von Lothi vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.414 Views
Lothi Themenstarter:in
344 Beiträge seit 2006
vor 12 Jahren
In welcher Art und Weise stelle ich Daten und Listen zur Verfügung (List<T>, BindingList<T>, ...)

Hallo zusammen

Mir kam einfach kein besserer Titel in den Sinn.

Ich bin dabei eine dll zu erstellen, welche geparste Objekte aus Textdateien als Objekte und Listen zur Anzeige oder Weiterverarbeitung bereit stellt.
Da ich nicht weiss was mit den Daten weiter gemacht wird (Consolen Anwendung, Internet, WPF, Forms...), weiss ich jetzt nicht genau, wie und in welcher Form ich die Listen zur Verfügung stellen soll.

Soll ich schon in meiner DLL überall INotifyPropertyChanged impementieren und BindingList<T> zurückgeben. Oder einfach normale Listen (List<T>, Collection<T>).
Die Daten können auch nur für Berechnungen benutzt werden, die dann nicht gebunden werden.

Wie ist das vorgehen?

Vielen Dank und Gruss
Lothi

1.552 Beiträge seit 2010
vor 12 Jahren

Hallo Lothi,

Soll ich schon in meiner DLL überall INotifyPropertyChanged impementieren und BindingList<T> zurückgeben.

Nein, du stellst nur die Datenklassen zur Verfügung. Für die Benachrichtigung an die GUI, soll sich der Benutzer kümmern.

Oder einfach normale Listen (List<T>, Collection<T>)

Ja, schon bessern. Evtl bieten sich auch die IEnumerable<T> an, welche für diesen Zweck gut geeigntet sind. In Kombination mit yield kannst du bei den Methoden ermöglichen dass, wenn der Benutzer z.B. nur das erste Element der Liste benötigt, nicht die ganze Liste erstellt werden muss.

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo Lothi,

BindingList<T> ist meistens zu speziell, IEnumerable<T> in vielen Fällen schon wieder zu allgemein. List<T> ist recht universell. Wenn der Aufrufer was anders braucht, soll er es selbst konvertieren. Denn wie du schon selber sagst, weiß du nicht, was der Aufrufer damit anstellen soll. Entsprechend liegt es auch nicht in einer Zuständigkeit, da was vorauszuahnen.

Das gesagte bezieht sich entsprechend deiner Frage auf Rückgabetypen. Anders sieht es bei Parametertypen aus. Da sollte man so allgemein wie möglich sein (außer wenn dadurch die Implementierung der Methode unnötig verkompliziert würde oder ihre Aufwandsklasse signifikant steigen würde). Also wenn möglich, sollte man IEnumerable<T> wählen, damit der Aufrufer möglichst wenig eingeschränkt ist, welche Collection er nun konkret übergibt.

herbivore

Lothi Themenstarter:in
344 Beiträge seit 2006
vor 12 Jahren

Hallo

Vielen Dank für die Ratschläge.
Wenigstens bin oder war ich nicht ganz auf dem Holzweg. Habe mich ein bisschen mit der Datenbindung beschäftigt und wurde dadurch unsicher.
Werde also bei List<T> bleiben.

Vielen Dank und Gruss
Lothi

C
1.214 Beiträge seit 2006
vor 12 Jahren

Ich würde bei Rückgabewerten eher zu einer IEnumerable<T> tendieren oder vielleicht IReadOnlyCollection<T> oder sogar Arrays.
Das Problem ist, dass eine List<T> veränderbar ist. Das muss natürlich kein Problem sein, aber ich finde es konzeptionell nicht schön. Du hast eine Schnittstelle, über die du eine (evtl. geordnete) Menge von Objekten bekommst. Alles andere sind Implementierungsdetails. In DIESE Liste etwas einzufügen, macht meist keinen Sinn. Die wird ja eh nicht automatisch mit dem Speichermedium synchronisiert. Ich finde, eine saubere Schnittstelle muss so wenig Interpretationsspielraum wie möglich lassen.

5.742 Beiträge seit 2007
vor 12 Jahren

Das Problem ist, dass eine List<T> veränderbar ist. Das muss natürlich kein Problem sein, aber ich finde es konzeptionell nicht schön.

Sehe ich ähnlich: Wenn ich von einer Property eine List<T> zurückbekomme, erwarte ich, dass Änderungen an der Liste auch von der Klasse übernommen werden, d.h. ich nicht jedes Mal eine neue Kopie der Liste erhalte.

Daher verwende ich meist IEnumerable<T> - mit Arrays hat man auch wieder das Problem, dass man im Getter kopieren muss, um sicher zu stellen, dass niemand das "interne" Array der Klasse modifiziert.

Diese Einstellung zu dem Thema hat sich bei mir hauptsächlich aufgrund von LINQ (to Objects) entwickelt:
Aus einem IEnumerble<T> kann man dadurch ganz schnell und leicht ein Array oder eine Liste machen.

Anderseits hat man (nach Aufrufen von Erweiterungsmethoden) auch häufig nur ein IEnumerable<T> und müsste somit nur zwecks Rückgabewert_ List<T>_ eine Liste daraus erzeugen.
Aufpassen muss man dann nur im Zusammenhang mit Lazy Evaluation - ich persönlich rufe daher meist ToArray() auf einen Ausdruck auf, um die Ausführung zu erzwingen. Als Rückgabewert verwende ich jedoch trotzdem_ IEnumerable<T>_.

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo zusammen,

natürlich sollte klar sein, ob die Liste eine Kopie oder ein Original ist. Im Startbeitrag war die Rede von "geparsten Objekten aus Textdateien als Objekte und Listen zur Anzeige oder Weiterverarbeitung". In dem Kontext ist es m.E. klar, dass es um eigenständige Listen geht und jeder Aufruf eine neue Liste liefert. Wenn das so ist, ist es völlig unproblematisch, wenn die Liste anschließend verändert wird. Der Aufrufer bekommt die Liste quasi geschenkt. Es ist seine Liste. Er kann damit machen, was er will. Und damit er das gängige direkt machen kann, ist es schön, wenn es eine List<T> ist.

Zumal die Verwendung von IEnumerable<T> auf halbem Weg stehen bleibt, denn sie beantwortet nicht die Frage, ob die Elemente der Auflistung Originale oder Kopien sind und was somit passiert, wenn man diese ändert. Die Verwendung von IEnumerable<T> verhindert auch nicht, dass die Elemente geändert werden können.

Ich will ja gar nicht sagen, dass es keinen Sinn macht, in bestimmten Situationen IEnumerable<T> als Rückgabetyp zu verwenden. Aber es auch nicht die einzig richtige Möglichkeit.

herbivore

2.187 Beiträge seit 2005
vor 12 Jahren

Hallo @All,

Über IList<T>, IEnumerable<T> und BindingList<T> wurde ja schon genug erzählt aber INotifyPropertyChanged wurde hier völligst ignoriert.

Die Liste implementiert INotifyPropertyChanged vermutlich nicht aber die Objekte/Klassen die eine Assembly zurück gibt könnten dieses Interface implementieren, da es ansonsten ein unglaublicher aufwand ist wenn die Objekte an einer stelle eingesetzt werden wo dieses Obeserver-Pattern verwendet wird (z.B. Win-Forms). Nicht jede Klasse muss INotifyPropertyChanged implementieren, aber bei jeder Klasse ist es eine Überlegung wert es zu tun (meiner Meinung nach).

@Lothi: Sind die geparsten Objekte die du zurück gibst von einer Klasse aus deinem Assembly oder von extern? Wenn ja würde ich wirklich mal überlegen ob INotifyPropertyChanged implementiert werden soll.

Gruß
Juy Juka

Lothi Themenstarter:in
344 Beiträge seit 2006
vor 12 Jahren

Hallo

Die Objekte erstelle ich aus einer Textdatei, welche ich von einem externen Programm bekomme. Das Programm erwartet dann auch wieder ein gleiches Format zurück.

Sieht vereinfacht so aus:


BATCH_RECIPE NAME="OP_AUSTR_GS" TYPE=OPERATION CATEGORY="Recipes/Operations"
 user="ADMINISTRATOR" time=1315290854/* "06-Sep-2011 08:34:14" */
{
  DESCRIPTION="Grundschichtaustrag OP Zentrifuge"
  FORMULA_PARAMETER NAME="FP_BESCHREI_TEXT" TYPE=UNICODE_STRING
  {
    CONNECTION=INPUT
    RECTANGLE= { X=-50 Y=-50 H=1 W=1 }
  }
  ATTRIBUTE_INSTANCE NAME="FP_BESCHREI_TEXT"
  {
    VALUE { CV="" }
  }
}

Also eine Klasse Operation ("OP_AUSTR_GS") die in einer 1:n Beziehung mit der Klasse Parameter steht.
Vom User darf nur VALUE geändert werden.
Will der User eine neue Operation erstellen, wird eine Kopie von der Standart Operation erstellt, der er ein neuen Namen geben muss, wenn die alte nicht überschrieben werden soll. Das zu prüfen ist die Sache vom Benutzer.

Der Benutzer meiner DLL, bekommt von mir eine Klasse OperationListe, aus der er alle Operationen mit den Parameter bekommt.
Ich erwarte dann von ihm eine geänderte Operation oder geänderte Operationen in einer Liste zurück.
Diese Daten werden dann wieder als Textdatei gespeichert, die vorhanden OP überschrieben, die Neuen neu angelegt.

Wie der User die Value-Werte ändert weiss ich nicht. Wenn ich jetzt mein geschreibsel so lese, glaube ich nicht, dass ich INotifyPropertyChanged brauche.

Das Designe ist komplizierter als ich am Anfang vom Projekt gedacht habe. 8)
Gruss Lothi