Création d'une liste générique des objets en C#
Par la voie de l'intro, je suis en création d'un Quadtree moteur à des fins personnelles à des fins de formation. Je suis désireux de ce moteur pour avoir la capacité de travailler avec de nombreux différents types de formes (au moment où je vais avec des cercles et des carrés) qui vont tous se déplacer dans une fenêtre et effectuer une action lors de la collision se produit.
Voici mes objets de forme que j'ai jusqu'à présent:
public class QShape {
public int x { get; set; }
public int y { get; set; }
public string colour { get; set; }
}
public class QCircle : QShape {
public int radius;
public QCircle(int theRadius, int theX, int theY, string theColour) {
this.radius = theRadius;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
public class QSquare : QShape {
public int sideLength;
public QSquare(int theSideLength, int theX, int theY, string theColour) {
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
Maintenant, ma question est, comment puis-je créer une liste générique (List<T> QObjectList = new List<T>();
) en C# donc je peux avoir une liste contenant toutes ces formes diverses qui peuvent avoir des propriétés différentes (par exemple, QCircle a le "rayon" de la propriété, tandis que QSquare a la "sideLength de la propriété")? Un exemple de mise en œuvre serait utile.
Je sais juste qu'il est bêtement évident de répondre à cette question, mais j'apprécierais toute aide de toute façon. Je suis en train de revenir en C#; il a évidemment été un moment...
Une telle liste, on retrouve les classes qui héritent de QShape? Si oui, j'ai été à droite; la réponse est bêtement évident.
Oui, il le ferait. Mais vous ne pourrez accéder à la QShape propriétés à moins de vous jeter des objets individuels.
Pourrais-je obtenir que dans le formulaire de réponse, y compris un exemple de comment vous pouvez mettre en œuvre que (c'est à dire, comment vous pouvez accéder à QCircle et QSquare propriétés spécifiques de la Liste<QShape>)?
Vous ne pouvez pas. Je ne sais pas pourquoi son commentaire est upvoted. Vous avez clairement l'état que vous souhaitez accéder aux différentes propriétés qui ne sont pas contenues dans le parent de la classe à l'aide de la classe de base comme le type ne fonctionnera pas.
OriginalL'auteur Djentleman | 2012-07-06
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin d'utiliser de passer
Stocker les objets dans une liste avec la classe de base
Vous pouvez ensuite sortie de l'objet en toute sécurité si vous savez ce que c'est par exemple
Vous pouvez également implicitement abattu objets
Pour plus d'informations, lisez l'Upcasting et de Passer des sections ici
Je ne suis pas tout à fait sûr de ce que tu veux dire, c'est une alternative à une interface de type d'accès des propriétés spécifiques.
Je crois que vous pouvez utiliser l'option mot-clé dans votre exemple, il est disponible depuis un certain temps. si(monobjet est MyType)
Merci, je ne savais pas à ce sujet.
J'apprends beaucoup de choses que je ne connaissais pas sur ce site... tous les jours en fait, je pense que j'apprends quelque chose de nouveau.
OriginalL'auteur Joel
Vous devez mettre en œuvre une
Interface
. Par exemplePuis dans la mise en œuvre, vous pouvez faire
Enfin, dans votre liste:
Maintenant votre liste peut contenir TOUT ce qui implémente
IHasLength
si c'est unQCircle
,QShape
, ou même unQDuck
si vous voulez tant qu'il implémenteIHasLength
.Parce que vos classes n'ont pas de propriété commune de tous les noms. Donc, si vous deviez créer une liste de
QShape
et je voulais effectuer une itération sur elle et obtenir la longueur de toutes les formes, deQCircle
etQSquare
vous ne pouvez pas. Si vous implémentez l'interface, puis vous serez en mesure de le faire.Ahh, je vois. Très agréable. De temps à lire sur les interfaces! Merci 🙂
Juste une note rapide pour votre bénéfice. Je suis allé avec ce genre de démarche, sauf que j'ai changé d'IHasLength à ISpatialNode. Cette interface est pour x,y de positionnement. Plus de sens, et signifie que je peux ajouter n'importe quel objet qui nécessite le positionnement dans mon Quadtree.
Bien sûr, vous voulez utiliser les noms/propriétés de sens pour votre mise en œuvre. Je viens de choisir
Length
pour l'exemple puisque c'est ce que vous avez mentionné dans votre question (radius
,sideLength
). Je suis sûr que tout est clair maintenant 😉OriginalL'auteur Pete
Vous pouvez stocker dans un
List<QShape>
mais cela voudrait dire que vous ne pourriez pas accéder à propriétés spécifiques à un type.Généralement, vous pourriez aborder ce en fournissant une interface commune dans votre classe de base, et en remplaçant le comportement dans les sous-classes. De cette façon, une interface commune peut en cacher une communauté variée de comportements. Par exemple, un
Grow
méthode pourrait masquer la complexité croissante des éléments de différentes formes et peut être appelée sans autorisation explicite des connaissances de la forme sur laquelle il est en fonctionnement.J'utilise le terme d'interface dans un lâche de la mode. Tous les objets ont une interface en vertu de l'offre des méthodes et des propriétés... et pas seulement ceux qui héritent d'un
interface
mise en œuvre.Gotcha... merci.
J'aime bien, semblable à Pete de réponse. Merci!
OriginalL'auteur spender
Est-ce que vous souhaitez?
Une question: ne Serait-il pas plus efficace pour parcourir la liste une fois et d'effectuer des actions sur les différents types à l'aide des instructions conditionnelles dans dit itération, plutôt que de parcourir en deux fois (une fois pour chaque forme) que vous avez ici?
Oui, mais...Pour les petites listes (<10 000 éléments), il fait probablement pas de différence. C'est vraiment pas clair à partir de l'OP de ce que les objectifs et les exigences.
OriginalL'auteur ja72
J'ai l'impression de manquer quelque chose mais...
et
fonctionne parfaitement bien.
EDIT:
Ah, je ne comprenais pas ce qui était demandé.
Oui, que votre
QCircle
etQSquare
les classes héritent deQShape
, vous pouvez le faire.Il est intéressant de noter que si vous souhaitez accéder à la
radius
propriété de tous lesQCircle
's dans cette liste, alors vous allez avoir à filtrer la liste en fonction de leur type.Oui, ça fonctionne, mais il veut UNE liste de tenir n'importe quel type de
QShape
,QCircle
, etQSquare
.J'aurais été plus clair, mais je suis désireux d'une seule liste, si possible.
Votre modifier clarifier les choses, merci 🙂
OriginalL'auteur Alastair Pitts
Vous pouvez utiliser Ian Mercer commentaire
List<QShape>
Et voici comment le remplir:
Lui unbox:
Si vous avez besoin d'appeler une méthode, au large de la classe de base, pas besoin de unbox viens de l'utiliser.
OriginalL'auteur Chris Gessler
Stockage
Vous êtes déjà sur la bonne voie avec vos définitions de classe. Ce que vous avez à faire est de faire une
List
de la super-classe (dans ce cas,QShape
), qui sera en mesure de contenir tous vos formes.Voici un exemple de la façon dont vous feriez:
Accès
Le problème ici est de différencier ce qui est ce que une fois que tout est dans la liste. C'est fait avec le
getType()
ettypeof()
méthodes de C#. (Jon Skeet a une excellente réponse sur la façon de le faire). En gros, ça ressemble à ça:Après vous faites cela, vous pouvez continuer à utiliser vos objets comme normal. Mais si vous essayez d'accéder à partir de la liste, vous pouvez uniquement utiliser les méthodes et les variables qui
QShape
a, comme chaque objet mis dans la liste sera jeté à elle.Même si certains peuvent apparaître pour être à l'extérieur, je comprends ce que vous dites, alors merci!
essais d'un type de l'objet pour l'égalité avec un type connu n'est pas le même que le
is
de l'opérateur (et 99% du temps, le programmeur voulait le comportement de lais
de l'opérateur, de toute façon, de sorte que le type de contrôle d'égalité est généralement un bug).Je faisais allusion à la uncompilable (non-C#) code
OriginalL'auteur Jon Egeland
ensuite ce faire
OriginalL'auteur Bulelani Cimani