1

我试图找出一个可以轻松地动态修改对象的系统。

这是一个例子,假设我有一个继承自 Entity 的 Entity2D。Entity2D 有一个 Position 属性。

现在我有一个继承自 Modifier 的类 ModifyPosition。

这是一些代码

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

但是,如果您每秒多次调用它,我认为投射会减慢它的速度。

有没有另一种方法可以解决这个问题而不必投射?

4

3 回答 3

1

如果您使用接口 IEntity

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

让实体实现该接口

public class Entity: IEntity
{
...
}

并将其用作 Apply 的参数类型

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

那么你不必投射

于 2010-07-21T23:58:03.607 回答
0

尝试这样的事情:

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

这看起来很容易阅读和安全——希望它对你有用。

于 2010-09-02T02:46:32.970 回答
0

使用 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;
    }
}
于 2010-07-22T00:31:10.793 回答