J'essaie de créer un "inventaire" simple d'articles, un peu comme dans n'importe quel RPG. J'ai les classes em> faits, qui ont des propriétés. De toute façon, j'ai une classe de base de J'ai le code suivant (désolé si la lisibilité est horrible): p> essentiellement, ce que je 'M Essayer de faire est d'ajouter une nouvelle arme code> à l'inventaire, mais l'inventaire est une liste ('shopsystem.item' ne contient pas de définition pour "ATK" et Aucune méthode d'extension 'ATK' Accepter un premier argument de type 'Shopsystem.item' pourrait être trouvé) em> p> Alors, y a-t-il un moyen de réaliser ce que j'avais l'intention de réaliser ici? Avoir un "inventaire" qui peut stocker des objets code> objet code>, ainsi que Merci beaucoup de lecture. P> Voici le < Code> item code> et élément code> et héritage de celui-ci est arme code> . élément code> a des propriétés (nom, valeur, poids, "élément important") également utilisé dans arme code>, mais arme code> a des propriétés supplémentaires (attaque , défense, vitesse, rendement). p> arme code> n'ont pas accès à: p> arme code>, armure code>, accessoire code> etc. objets , qui hérit de article code>? Il convient également de mentionner que je peux accéder à toutes les propriétés souhaitées si je déclare les suivantes: p> arme code> classes, si quelqu'un est intéressé: p>
5 Réponses :
Afin d'accéder aux propriétés spécifiques à la classe héritée, vous devez vous lancer sur le type de classe de béton approprié. Donc plutôt que d'accéder à aussi, si vous effectuez des tâches communes qui auront des tâches communes qui auront Différentes implémentations basées sur la classe sous-jacente, telle que la journalisation des valeurs à la console (que je réalise a été effectuée pour tester, mais est un bon exemple de toute façon), vous devez mettre en œuvre une méthode ultérieure dans la classe de base. P> Par exemple, dans la classe de base: p> et dans la classe d'armes: p> alors, pour accéder à ceci : p> inventaire [0] code>, vous devez accéder à l'inventaire (arme) [0] code>.
Si j'utilise (arme) inventaire [0] .atk code>, je reçois toujours le même message d'erreur.
Essayez d'utiliser (arme) inventaire [0]). ATK à la place
Excellent! S'il vous plaît voir ma réponse mise à jour pour une suggestion supplémentaire.
L'utilisation d'une distribution statique échouera sur des éléments qui types d'objets autres que l'arme. Un InvalidCastException code> sera lancé. Il peut être préférable d'utiliser une distribution dynamique.
Merci, @competent_tech! Je vais avoir besoin d'une méthode comme celle pour le débogage, de sorte que cela facilitera beaucoup les propriétés. @Monrothomes Donc, il serait préférable d'utiliser une distribution dynamique si je ne savais pas quel type serait, par exemple, l'inventaire [3]? Ce serait un contexte plus probable lorsque ce système est opérationnel.
Vous pouvez implémenter une interface commune (par exemple, iITEM code>) à travers laquelle vous interrogez des propriétés des éléments ou de mettre en œuvre une classe de base commune, probablement un abstrait et utilisez-le comme le type T code> de la liste code>.
Si vous utilisez cette dernière option, assurez-vous de remplacer les fonctions de la classe de base, le cas échéant, le polymorphisme fera le reste. P>
Vous devrez jeter la valeur à un Vous devez également distinguer entre les différentes classes (par exemple, vous avez probablement aussi un Cependant, un meilleur approche serait d'utiliser l'héritage - let arme code> afin d'accéder à ces propriétés, c'est-à-dire l'inventaire ((arme) [0]). ATK) code>. Notez les parenthèses: la coulée a une déficience inférieure à celle de l'accès au champ, vous ne pouvez donc pas écrire (arme) inventaire [0] .atk code>; qui serait interprété comme (arme) (inventaire [0] .atk) code>. armure code> classe). Le plus simple à faire serait d'ajouter une valeur supplémentaire sur la classe de base élément code> qui vous indique le type réel de l'objet, puis de jeter en conséquence. P> élément code> Définir une série de méthodes pouvant gérer toutes les trucs génériques - par exemple Affichage des informations sur l'article - puis la remplacer dans les classes héritantes. C'est-à-dire au lieu d'accéder directement à toutes ces données, vous appelez à une méthode qui le combine de manière raisonnable. Pour votre exemple particulier, vous convertissez l'élément en une chaîne. Il serait donc logique de remplacer la radiographie () - cela signifie que vous pourrez le faire: P> public string ToString() {
//Put all of the data in here, like in your example
return String.Format("Name: {0}\n...", name, ...);
}
J'aime cette méthode de totring. Cependant, si je voulais accéder à une seule de ces propriétés (disons, la propriété .ATK) à utiliser dans une formule mathématique? Serait-il préférable de garder la façon dont il est i.e. ((arme) inventaire [0]). ATK code>? La chaîne que je faisait était simplement de tester que les valeurs stockaient correctement.
@Deadrust: Oui, vous pouvez le faire et vous pouvez également faire arme usagon useappon = (arme) inventaire [0]; code>, puis accédez à toutes les propriétés de l'utilitaire sans couplage supplémentaire. Vous voudrez probablement le faire, même plus tôt, par exemple. Stockage de l'arme actuellement équipée sur un lecteur code> ou unité code>, mais les RPGS varient de leur approche à cette approche.
Gardez également à l'esprit que vous ne i> avez-vous i> d'utiliser Tostring pour cet exemple. Cela peut faire autant de sens de définir votre propre méthode et d'appeler cela - tout dépend de ce que vous avez l'intention de faire avec vos cours.
Vous faites la bonne chose en utilisant une liste Lorsque vous extrayez l'élément de la liste, il vous suffit de faire un peu de travail pour tester s'il s'agit d'une arme code> ou d'un autre type d'élément pour voir si l'élément en position Une autre façon de le faire consiste à vérifier le type à l'aide du <élément> code> pour stocker des éléments et des sous-classes d'articles! code>. < / p> i code> sur la matrice est un arme code>, utilisez l'opérateur comme code>, qui reviendra null code> si l'élément n'est pas le type spécifié (peut-être qu'il s'agit d'une armure ou d'un autre type d'élément). Ceci est connu sous le nom de dynamique code> coulée. Ça fonctionne même si l'élément est null code>. P> est code > Opérateur avant de faire un statique code> couler. p>
Meilleure alternative au deuxième test: si (inventaire [i] est arme) code>. Mais votre premier exemple (avec comme code>) est probablement préférable de toute façon, car il évite de casser l'objet deux fois. :)
@Danj Yep, merci! Cela évite également la nécessité de la vérification nulle. Réponse ajustée en conséquence. :)
Ce premier exemple est exactement ce que j'aurai besoin de suffisamment, lorsque je commence à ajouter de manière dynamique des éléments à l'instance code> inventaire code>. Merci beaucoup!
C'est là que Linq peut être votre ami lorsque vous traitez du polymorphisme. Le problème avec les éléments de casting est lorsque l'index indiqué n'est pas le type correct. (Ie Vous pouvez éviter L'exception en utilisant: p> Cependant, vous allez faire des chèques #null partout. Utilisation de LINQ Vous obtenez beaucoup de flexibilité: p> à partir d'ici, vous pouvez utiliser inventaire [0] code> n'est pas un arme code>, (arme) inventaire [0] code> va jeter.) où code>, sRevarefault code>, etc. Recherchez des données qui vous intéressent ou iTERE sur les armes. P> p>
+1 Ce serait mon approche, il limite à quel point votre code doit être conscient de l'inventaire générique. Par exemple, vous pouvez écrire une méthode qui agit sur une liste list inventaire.oftype