Als Einstieg kreiere ich eine grundlegende Quadtree-Engine für persönliche Lernzwecke. Ich möchte, dass diese Engine die Fähigkeit hat, mit vielen verschiedenen Arten von Formen zu arbeiten (im Moment gehe ich mit Kreisen und Quadraten), die sich alle in einem Fenster bewegen und irgendeine Art von Aktion ausführen, wenn eine Kollision auftritt / p>
Hier sind meine Formobjekte, wie ich sie bisher habe:
%Vor% Nun ist meine Frage, wie erstelle ich eine generische Liste ( List<T> QObjectList = new List<T>();
) in C #, so dass ich eine Liste mit all diesen verschiedenen Formen haben kann, die verschiedene Eigenschaften haben können (zB QCircle hat die Eigenschaft "radius" während QSquare) Hat die Eigenschaft "sideLength"? Ein Beispiel für die Implementierung wäre ebenfalls hilfreich.
Ich weiß nur, dass es eine dümmlich naheliegende Antwort auf diese Frage gibt, aber ich würde mich über jede Hilfe freuen. Ich versuche, wieder in C # zu kommen. Es ist offensichtlich eine Weile her ...
Sie müssen downcasting verwenden
Speichern Sie die Objekte in einer Liste mit der Basisklasse
%Vor%Sie können das Objekt dann sicher upcasieren, wenn Sie wissen, was es ist, z. B.
%Vor%Sie können Objekte auch implizit verkleinern
%Vor%Weitere Informationen finden Sie in den Abschnitten zu Upcasting und Downcasting hier
Sie sollten ein Interface
implementieren. Zum Beispiel
Dann können Sie in der Implementierung
tun %Vor%Schließlich in Ihrer Liste:
%Vor% Jetzt kann Ihre Liste alles enthalten, was IHasLength
implementiert, egal ob es ein QCircle
, QShape
oder sogar ein QDuck
ist, solange Sie IHasLength
implementieren.
Sie könnten sie in List<QShape>
speichern, aber das würde bedeuten, dass Sie nicht auf typspezifische Eigenschaften zugreifen konnten.
Im Allgemeinen können Sie dies erreichen, indem Sie eine allgemeine Schnittstelle in Ihrer Basisklasse bereitstellen und das Verhalten in Unterklassen außer Kraft setzen. Auf diese Weise kann eine gemeinsame Schnittstelle eine Vielzahl von Verhaltensweisen verbergen. Zum Beispiel könnte eine Grow
-Methode die Komplexität von wachsenden Objekten unterschiedlicher Form verbergen und ohne explizite Kenntnis der Form, auf der sie arbeitet, aufgerufen werden.
Ich fühle mich, als ob ich etwas verpasse, aber ...
%Vor%und
%Vor%wird perfekt funktionieren.
BEARBEITEN:
Ah, ich habe nicht verstanden, was gefragt wurde.
Ja, da Ihre Klassen QCircle
und QSquare
von QShape
erben, können Sie das einfach tun.
Es ist erwähnenswert, dass Sie, wenn Sie auf die Eigenschaft radius
aller QCircle
in dieser Liste zugreifen möchten, die Liste nach Typ filtern müssen.
Sie können Ian Mercers Kommentar List<QShape>
Und so würden Sie es füllen:
%Vor%Um es auszupacken:
%Vor%Wenn Sie eine Methode von der Basisklasse aufrufen müssen, müssen Sie sie nicht auspacken, verwenden Sie sie einfach.
Sie sind mit Ihren Klassendefinitionen bereits auf dem richtigen Weg. Was Sie tun müssen, ist ein List
der Oberklasse (in diesem Fall QShape
), die alle Ihre Formen enthalten kann.
Hier ist ein Beispiel, wie Sie es machen würden:
%Vor% Das Problem hier ist zu unterscheiden, was ist was alles in der Liste ist. Das haben wir mit den Methoden getType()
und typeof()
von C # gemacht. ( Jon Skeet hat eine ausgezeichnete Antwort darüber, wie man das macht ). Im Grunde sieht es so aus:
Nachdem Sie dies getan haben, können Sie Ihre Objekte wie gewohnt wieder verwenden. Wenn Sie jedoch versuchen, sie über die Liste aufzurufen, können Sie nur die Methoden und Variablen verwenden, die QShape
enthält, da jedes in die Liste aufgenommene Objekt in diese Liste umgewandelt wird.