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