2010-07-21 5 views
1

J'essaye de comprendre un système qui peut facilement modifier des objets à la volée.Modifier le système C#

Voici un exemple, Disons que j'ai un Entity2D qui hérite de Entity. Entity2D a une propriété Position.

Maintenant, j'ai une classe appelée ModifyPosition qui hérite de Modifier.

Voici un code

public class Entity 
{ 
/// <summary> 
/// Applies the modifier to this entity. 
/// </summary> 
/// <param name="modifier">The modifier to apply.</param> 
public void ApplyModifier(Modifier modifier) 
{ 
    modifier.Apply(this); 
} 
} 

/// <summary> 
/// Modifies an entities position 
/// </summary> 
public class ModifyPosition : Modifier 
{ 
    /// <summary> 
    /// Initializes a new instance of the <see cref="ChangePosition"/> class. 
    /// </summary> 
    /// <param name="position">The position.</param> 
    public ChangePosition(Vector2 position) 
    { 
     this.Position = position; 
     this.IsModifyingChildren = false; 
    } 

    /// <summary> 
    /// Gets the position. 
    /// </summary> 
    /// <value>The position.</value> 
    public Vector2 Position { get; private set; } 

    /// <summary> 
    /// Applies this change to the specified entity. 
    /// </summary> 
    /// <param name="entity">The entity.</param> 
    internal override void Apply(Entity entity) 
    { 
     ((Entity2D)entity).X += this.Position.X; 
     ((Entity2D)entity).Y += this.Position.Y; 
    } 
} 

Mais si vous appelez cette opération plusieurs fois par seconde je pense que le casting serait ralentir.

Existe-t-il une autre façon de procéder sans lancer?

+0

qu'avez-vous fait, supprimez et posez à nouveau la question? Ce n'est pas un bon moyen d'obtenir des réponses –

+1

Il est probablement étrange d'avoir un objet qui vient modifier un objet de l'extérieur (et qui brise plusieurs lignes directrices). Y at-il une raison pour laquelle vous avez besoin de faire cela, par opposition à avoir le code de modification interne à l'objet? –

+0

@Lucas c'était un accedent ... =/et je n'ai pas pu lire les réponses qui ont été postées donc j'ai essayé de le demander ... désolé. Avez-vous répondu avant? Pourriez-vous republier votre réponse? encore désolé c'était mon erreur. @silky Je pensais que si j'avais un moyen de modifier l'objet de l'extérieur, il serait plus facile de pouvoir modifier les propriétés de l'objet à la volée comme dans un éditeur. –

Répondre

1

si vous utilisez une interface IEntity

interface IEntity 
{ 
double X{get;} 
double Y{get;} 
} 

ont Entity mettre en œuvre cette interface

public class Entity: IEntity 
{ 
... 
} 

et l'utiliser comme le type de paramètre pour Appliquer

internal override void Apply(IEntity entity) 
    { 
     entity.X += this.Position.X; 
     entity.Y += this.Position.Y; 
    } 

vous n'avez pas avoir à lancer

0

Avec C# vous devez vous assurer que le type que vous modifiez supporte votre modification (pas vrai avec certaines langues). Vos modificateurs devront donc savoir explicitement quels types ils modifient. (Alternativement, vos entités peuvent connaître les modificateurs, mais il semble plus raisonnable de donner les connaissances aux modificateurs.)

Je n'ai pas de réponse pour vous à ce stade; c'est ma tentative, mais j'obtiens une erreur de compilation dans la déclaration ModifyPosition.Apply indiquant que vous ne pouvez pas spécifier de contraintes de type sur une implémentation de méthode substituée.

public interface IPositionableEntity 
{ 
    Vector2 Position { get; set; } 
} 

public class Entity 
{ 
    public void ApplyModifier<T>(T modifier) where T : Modifier 
    { 
     modifier.Apply(this); 
    } 
} 

public class Entity2D : Entity, IPositionableEntity 
{ 
    public Vector2 Position { get; set; } 
} 

public class Vector2 
{ 
    public double X { get; set; } 
    public double Y { get; set; } 
} 

public abstract class Modifier 
{ 
    public abstract void Apply<T>(T entity); 
} 

public class ModifyPosition : Modifier 
{ 
    public ModifyPosition(Vector2 position) 
    { 
     Position = position; 
    } 

    public Vector2 Position { get; private set; } 

    //Compiler error here: 
    //Constraints for explicit interface implementation method are inherited 
    //from the base method, so they cannot be specified directly 
    public override void Apply<T>(T entity) where T : IPositionableEntity 
    { 
     entity.Position.X += Position.X; 
     entity.Position.Y += Position.Y; 
    } 
} 

EDIT - Voici une au moins compile. Le seul changement est à ModifyPosition.

public class ModifyPosition : Modifier 
{ 
    public ModifyPosition(Vector2 position) 
    { 
     Position = position; 
    } 

    public Vector2 Position { get; private set; } 

    public override void Apply(object entity) 
    { 
     if (!(entity is IPositionableEntity)) 
     { 
      return; //throw, whatever 
     } 

     var positionableEntity = (IPositionableEntity) entity; 
     positionableEntity.Position.X += Position.X; 
     positionableEntity.Position.Y += Position.Y; 
    } 
} 
+0

Intéressant, cela pourrait fonctionner, mais il pourrait être intéressant d'avoir beaucoup d'interfaces attachées à une classe quand il commence à avoir un beaucoup de propriétés que vous voulez changer. –

+0

Voir mon commentaire sur votre question - Je ne pense pas qu'il sera possible de résoudre ce problème aussi génériquement que vous le souhaitez en C#. – arootbeer

+0

Votre modification ne vous aiderait pas à diffuser de nouveau. –

0

Essayez quelque chose comme ceci:

class CatEntity : Entity, IModifiablePosition 
{ 
    // Interface method 
    public void ModifyPosition(Vector2 blah) { ... } 
... 
} 


class RobotEntity : Entity, IModifiableShader, IModifiablePosition 
{ 
// Interface method 
public void PushShader(RobotEffect bleh) { ... } 
public void ModifyPosition(Matrix blah) { ... } 
... 
} 

class ShaderModifier : IModifier 
{ 
    public override void Apply(IModifiableShader obj) 
    { 
    obj.PushShader(m_furryEffect); 
    } 
} 

class PositionModifier : IModifier 
{ 
    public override void Apply(IModifiablePosition obj) 
    { 
    obj.ModifyPosition(m_mxTranslation); 
    } 
} 

Cela semble facile à lire et sûr - espérons que cela fonctionne pour toi.

Questions connexes