1

その場でオブジェクトを簡単に変更できるシステムを見つけようとしています。

ここに例があります。エンティティから継承する 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

if you use an interface IEntity

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

have Entity implement that interface

public class Entity: IEntity
{
...
}

and use that as the parameter type for Apply

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

then you don't have to cast

于 2010-07-21T23:58:03.607 に答える
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 に答える
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 に答える