我试图找出一个可以轻松修改对象的系统。
这是一个例子,假设我有一个从Entity继承的Entity2D。 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;
}
}
但是,如果你每秒多次调用它,我会认为施法会减慢速度。
还有其他方法可以解决这个问题吗?
答案 0 :(得分: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;
}
然后你不必施放
答案 1 :(得分: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;
}
}
答案 2 :(得分: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);
}
}
这似乎很容易阅读和安全 - 希望它适用于你。