2010-07-21 73 views
1

我想弄清楚一個可以輕鬆修改對象的系統。修改器系統C#

這裏是一個例子,可以說我有一個從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

你做了什麼,刪除並重新提問?不是一種很好的方法來獲得答案 – 2010-07-21 23:58:22

+1

讓一個對象來自外部並修改一個對象(並且可以打破幾個指導原則)可能很奇怪。是否有任何理由需要這樣做,而不是將修改代碼放在對象內部? – 2010-07-21 23:58:26

+0

@盧卡斯這是一個accedent ... = /和我沒有得到閱讀已發佈的答案,所以我試圖重新問它...對不起。你之前回答過嗎?你介意重新發布你的答案嗎?再次抱歉,這是我的錯誤。 @silky我在想,如果我有辦法從外部修改對象,那麼它就會更容易在編輯器中更改對象的屬性。 – 2010-07-22 00:03:02

回答

1

,如果你使用一個接口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

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

編輯 - 這裏有一個至少編譯。唯一的變化是修改位置。

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

有趣的是,這可能會工作,但它可能會厭倦有一個類,當它開始有一個很多接口很多你想改變的屬性。 – 2010-07-22 00:34:23

+0

看到我對你的問題的評論 - 我不認爲這將是可能的一般解決這個問題,你想在C#中。 – arootbeer 2010-07-22 00:44:31

+0

您的編輯不會幫助您再次投射。 – 2010-07-22 08:08:25

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

這似乎容易閱讀和安全 - 希望工程爲雅。