Модификатор системы C # - PullRequest
1 голос
/ 22 июля 2010

Я пытаюсь выяснить систему, которая может легко изменять объекты на лету.

вот пример, допустим, у меня есть Entity2D, который наследуется от Entity. Entity2D имеет свойство Position.

Теперь у меня есть класс с именем ModifyPosition, который наследуется от Modifier.

Вот код

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;
    }
}

Но если вы вызываете это несколько раз в секунду, я думаю, что кастинг замедлит его.

Есть ли другой способ сделать это без необходимости разыгрывать?

Ответы [ 3 ]

1 голос
/ 22 июля 2010

если вы используете интерфейс IEntity

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

имеет сущность, реализующую этот интерфейс

public class Entity: IEntity
{
...
}

и используйте это как тип параметра для Применить

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

тогда вам не нужно разыгрывать

0 голосов
/ 02 сентября 2010

Попробуйте что-то вроде этого:

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);
  }
}

Это кажется легко читаемым и безопасным - надеюсь, это сработает для вас.

0 голосов
/ 22 июля 2010

С C # вы должны убедиться, что тип, который вы изменяете, поддерживает ваши изменения (не верно для некоторых языков). Таким образом, ваши модификаторы должны будут четко знать, какие типы они модифицируют. (С другой стороны, ваши сущности могут знать о модификаторах, но кажется разумнее дать модификаторам знания.)

На самом деле у меня нет ответа для вас на данный момент; это моя попытка, но я получаю сообщение об ошибке компилятора в объявлении ModifyPosition.Apply, в котором говорится, что нельзя указывать ограничения типа в реализации переопределенного метода.

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;
    }
}

РЕДАКТИРОВАТЬ - Вот тот, который по крайней мере компилируется. Единственное изменение - 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;
    }
}
...