2009-04-06 7 views
0

Cette fois, j'ai un problème avec les champs virtuels.Polymorphisme C# encore une fois - propriétés virtuelles

J'ai classe de base pour mes objets de jeu. Cette classe contient un champ avec un objet de classe Model. L'objet du modèle contient des valeurs telles que la position, etc.

Maintenant, en dessin, j'ai besoin de lire la position de chaque objet de son modèle. Le problème commence quand au lieu de classe de modèle par défaut j'utilise dérivé. Exemple:

abstract class GenericGameObject { public DefaultGameObjectModel Model = new DefaultGameObjectModel(); } 
class Plane : GenericGameObject { public void shoot(Missile m){ m.Model.Position.X = 10; } } 
class Missile : GenericGameObject { public new MissileModel Model = new MissileModel(); } 

class DefaultGameObjectModel { public Vector2 Position = new Vector2(){X=0}; } 
class MissileModel : DefaultGameObjectModel { } 

Plane p = new Plane(); 
Missile m = new Missile(); 
p.shoot(m); 
// NOT OK! ((GenericGameObject)m).Model.Position.X == 0 

J'ai essayé de modèle défini comme la propriété virtuelle au lieu de champ, mais cela échoue parce que propriétés dérivées doivent être de même type que leur base. Casting est futile car il y aura beaucoup d'autres types de modèles. Que puis-je faire si je veux lire une valeur de la classe dérivée, pas de la base?

Répondre

3

Il semble que votre GenericGameObject a besoin d'être un type générique, où le paramètre de type dérive de DefaultGameObjectModel:

abstract class GenericGameObject<TModel> 
    where TModel : DefaultGameObjectModel 
{ 
    private TModel model; 

    // Or whatever 
    public TModel Model 
    { 
     get { return model; } 
     protected set { model = value; } 
    } 
} 
+0

Cela semble être une bonne réponse à ma question, je n'ai qu'un autre problème: le type d'objet de jeu nécessite le type exact de modèle, et maintenant je peux utiliser n'importe quel type de création d'objet. En outre, MissileModel pourrait contenir des méthodes supplémentaires qui ne seraient pas visibles dans Missile sans lancer:/ –

+0

Je pense que vous avez mal compris. Vous pourriez toujours avoir un type de missile, qui dériverait de GenericGameObject . Ensuite, vous pourrez toujours voir les méthodes MissileModel car le modèle est fortement typé. –

1

Vous pouvez également créer une interface IGameObjectModel puis la mettre en œuvre dans chacune de vos classes Object Model. Votre GameObject aurait alors une instance de IGameObjectModel.

+0

Je voudrais l'idée, mais la classe de base contiendrait du code qui est partagé dans toutes les classes dérivées (en mouvement, en rotation, etc.). Je casserais la règle DRY dans ce cas. –

+0

Vos classes de base peuvent toujours hériter de la classe DefaultGameObjectModel et posséder leur propre implémentation de l'interface. –

+0

Dans ce cas, vous avez raison bien sûr. Je pense qu'il serait étrange d'avoir à la fois la classe de base et l'interface pour la même chose :) Mais il peut être résolu de cette façon –

Questions connexes