![]() |
Container-Klassen in Delphi
Liste der Anhänge anzeigen (Anzahl: 2)
Container-Klassen in Delphi
Verwalten von Objekten mit Hilfe von Container-Klassen am Beispiel eines Memory Spieles In diesem Tutorial geht es darum, wie man Objekte mit einer Container-Klasse verwalten kann. Demonstriert wird das ganze an Hand der Implementierung eines einfachen Memory Spieles. Bitte guckt es euch mal an und sagt mir, wo man noch was ergänzen oder verbessern könnte. |
Re: Container-Klassen in Delphi
Moin Michael,
bei Deinem C#-Beispiel: Zitat:
|
Re: Container-Klassen in Delphi
Ich weiß. Aber zum einem wollte ich das Beispiel möglichst dem Delphi Beispiel ähnlich halten, damit man leichter vergleichen kann und zum anderen könnte man den Wrapper brauchen, wenn man der Container-Klasse noch einige Features mitgeben will. Aber natürlich hast du recht, wenn du sagst, dass sie in diesem Beispeil eigentlich überflüssig ist. Das kann ich ja noch im Tutorial ergänzen.
|
Re: Container-Klassen in Delphi
Dann lass doch einfach die Verwendung der Generics weg und nimm' ne normale Liste. Dann kannst Du ja im Kommentar erwähnen, dass der .NET-typische Weg eigentlich die Verwendung der Generics wäre, Du hier aber, um die Parallelen zu zeigen, auf eine klassische Liste zurückgegrifefn hast.
|
Re: Container-Klassen in Delphi
Auch sollte der Wrapper auf jeden Fall IList<T> implementieren, wodurch der Code aber schnell mal doppelt so lang wie bisher werden könnte ;) .
Es ist einfach so, dass die BCL einem in den allermeisten Fällen keinen Grund gibt, einen eigenen Wrapper zu schreiben. Brauche ich eine strunzdumme Liste, nehme ich List<T>, brauche ich eigene Logik, erbe ich von Collection<T>. Der Blick über den Tellerrand ist eine schöne Idee, aber zeigt er eben nur die Syntax von C# und das Vorhandensein eines GC und nicht das Eigentliche: Wie ein .Net-Entwickler das Problem lösen würde. Entweder würde ich mir noch irgendeine für Personen-Objekte vernünftige Prüfung vor dem Einfügen in die Liste ausdenken[*] und dann das Ableiten von Collection<Person>, Überschreiben von InsertItems und schließlich auch die Benutzung der entstandenen Klasse zeigen, oder, wie du schon sagtest, das Beispiel stehen lassen und den Text noch etwas weiter ausführen (ArrayList würde ich eher nicht verwenden, denn das hat dann wirklich nicht mehr viel mit .Net-Code zu tun), wobei du dann noch zwei Kleinigkeiten ändern könntest: Den Cast im Getter kannst du weglassen, denn gerade dafür hast du ja die generische innere Liste, ebenso die Namespace-Angabe von IEnumerator<T>, die eher verwirren dürfte und die du bei List<T> ja auch nicht verwendet hast. [*]Dir fallen bestimmt schönere Beispiele als "eine Liste, die nur Personen annimmt, deren Nachname mit A anfängt" ein :zwinker: . |
Re: Container-Klassen in Delphi
Das habe ich mir fast gedacht, das dieser Teil noch nicht ganz optimal ist. aber ich mache selber erst meine ersten ernsthaften gehversuche in C# (zwangsweise aus beruflichen Gründen).Ich werde ihn dann noch mal etwas überarbeiten. Danke für die Hinweise.
|
Re: Container-Klassen in Delphi
Zitat:
Hier mal Pseudo code, wie eine Liste aussehen kann, deren Elementtyp zwar generisch ist, aber T muss mindestens Person oder ein Nachfahre sein und einen öffentlichen, parameterlosen Konstruktor besitzen:
Delphi-Quellcode:
OK, man hätte gleich von List<T> ableiten können... *g*
type
PersonList<T> = public class(IList<T>) where T is Person, T has constructor; public method AddNew : T; method Add(item : T); property Count : Integer read Innerlist.Count; property Item[index : Integer] : T read InnerList[index] write InnerList[index]; default; protected property InnerList : List<T> := new List<T>(); readonly; implements IList<T>; // *plopp*, schon implementiert... end; implementation method PersonList<T>.Add(item : T); begin Innerlist.Add(item); end; method PersonList<T>.AddNew : T; begin result := new T(); Add(result); end; |
Re: Container-Klassen in Delphi
Hi Luckie,
nettes Tutorial (irgendwo her kenne ich das, aber es soll erst 4 Tage alt sein :gruebel: ). Eine Sache fiel mir auf, und ja ich weiß ich bin kleinlich, aber dennoch finde ich, dass du es wissen solltest :) Und zwar schreibst du in 3.: Zitat:
Eine Frage dazu habe ich noch: Warum nicht von TList erben, und dann die Add... Methoden mit neuen Parametern überschreiben? MfG xZise PS: Für ein Programm habe ich die Methode schon erfolgreich angewendet! Das funktioniert sehr gut, und ist richtig cool :) |
Re: Container-Klassen in Delphi
Zitat:
@Elvis: Wenn ich das nächtse Mal vor dem Problem stehe, einen Wrapper ohne eigene Logik schreiben zu müssen, werde ich dran denken, versprochen *g* . |
Re: Container-Klassen in Delphi
Zitat:
Code:
und irgendwie, muss ich ja den Rückgabetyp festlegen.
// benötigt für foreach
public System.Collections.Generic.IEnumerator<Person> GetEnumerator() { return innerList.GetEnumerator(); } |
Re: Container-Klassen in Delphi
Du benötigst auch beim Rückgabewert keinen vollqualifizierten Typnamen, wenn der entsprechende Namespace oder Typ importiert wurde, was wohl der Fall ist, wenn du List<T> ohne Namespace-Angabe verwendest.
|
Re: Container-Klassen in Delphi
Zitat:
Denn so wie du es jetzt hast, hast du nur eine öffentliche Methode GetEnumerator und vertraust darauf, dass der Compiler anhand dieses Namens und des Rückgabewertes entscheidungen trifft. Aber ohne IEnumerable<T> gibt es kein LINQ und viele andere Dinge gehen auch nicht. Eine Containerklasse sollte in .net alle Standardinterfaces implementieren, die auf sie zutreffen. Bei dir wäre das IList<T>, welches ICollection<T> und IEnumerable<T> mitbringt. |
Re: Container-Klassen in Delphi
Zitat:
|
Re: Container-Klassen in Delphi
Zitat:
Also für alle Datencontainer. IEnumerable<T> ist eine Spezialisierung für einen bestimmten Itemtypen. "LINQ over Objects" basiert auf IEnumerable<T>, genau wie viele Methoden von vielen Hunderten von Klassen mit IEnumerable<T> umgehen können. Es nicht zu implemetnieren würde heißen, dass deine Containerklasse nur so wie in Delphi wäre: Eine weitere Klasse. Mit der Implementierung ist sie eine richtige Containerklasse, auf die du Abfragen machen kannst, die du mit einem Call an eine andere Liste anhängen kannst,... Mit meinem Beispiel oben wäre folgende LINQ-Query möglich:
Delphi-Quellcode:
var persons := new PersonList<Person>();
// irgendws hinzufügen var personNames := (from p in persons where not String.IsNullOrEmpty(p.Name) select distinct p.Name).ToList(); |
Re: Container-Klassen in Delphi
Ich habe jetzt eine aktualisierte Fassung im ersten Posting hochgeladen. Die Modifikationen der Klasse, wie sie Elvis vorschlägt sind noch nicht eingearbeitet.
|
Re: Container-Klassen in Delphi
Zitat:
Ich sehe gerade, Luckie, dass du fast genauso wie ich es vorgeschlagen habe, hast du es umgesetzt. :mrgreen: MfG xZise |
Re: Container-Klassen in Delphi
Sorry wenn das jetzt hier leicht OT wird,
aber ich bin soeben ueber den Konstrukt
Delphi-Quellcode:
gestolpert.
type
PersonList<T> = public class(IList<T>) where T is Person, T has constructor; [...] Ich arbeite zwar seit mehr als 20 Jahren mit Pascal, aber diese Syntax ist mir neu und latuernich moechte ich wissen, was das ist und wie man es verwenden kann. Falls jemand einen Link zu einem Tutorial hat, waere ich dankbar. |
Re: Container-Klassen in Delphi
Das ist ja auch kein Pascal, sondern C#.
|
Re: Container-Klassen in Delphi
Nope, das ist Roberts Chrome-Schnipsel :zwinker: .
@mashutu: ![]() Kurz umrissen kannst du beim Benutzen der Klasse den Typparameter T durch einen beliebigen Typ ersetzen (wobei da noch die Constraints eine Rolle spielen, die du mitgequotet hast: T muss von Person abgeleitet sein und einen öffentlichen, parameterlosen Konstruktor haben).
Delphi-Quellcode:
var
list : PersonList<Customer>; // T = Customer (eine von Person abgeleitete Klasse) begin [...] list[0].Orders[...]; // Person besitzt keine Eigenschaft Orders, dennoch müssen wir nicht casten, da Item[] ja nicht Person sondern T zurückgibt. Und in unserem Fall ist T = Customer end; |
Re: Container-Klassen in Delphi
Danke an Lucky und Khabarakh fuer die kurze Info und den Link zu Chrome
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz