2012-04-24 55 views
0

我有兩個項目:ClientProjServerProj,它們共享一個SharedLibrary,其中包含我的遊戲的基本知識。如何覆蓋自定義庫類中的方法

在這個庫裏面,我有類GameObject這是許多其他遊戲物品繼承的基類。

Inside GameObject是一種SetPosition()方法。

這裏是我的問題:當我在客戶端上運行SetPosition(),我想添加一些額外的代碼/完全覆蓋的方法。然而,我希望添加的代碼涉及只存在於ClientProj名稱空間中的類,SharedLibrary對此類不知情。

是否有任何干淨的方式來重寫或擴展庫方法?

更新:請注意,GameObject的實例及其所有繼承它的事物都是在SharedLibrary命名空間中定義,包含和處理的。 ClientProj和ServerProj大部分只處理網絡,用戶和輸入/輸出。

+0

如果重寫SETPOSITION方法的定義中不包括的類引用您的客戶端庫,我沒有看到問題是什麼? – 2012-04-24 10:46:56

回答

3

您可以使用Proxy pattern,並有遊戲對象從代理類,而不是真正的類繼承:

SharedLibrary:

public class GameObject 
{ 
    public virtual void SetPosition() { ... } 
} 

public class DelegatingGameObject : GameObject 
{ 
    public GameObject Inner; 
    public override void SetPosition() { Inner.SetPosition(); } 
} 

public class Tree : DelegatingGameObject 
{ 
} 

ClientLibrary:

class ClientGameObject : GameObject 
{ 
    public override void SetPosition() 
    { 
     if (isMonday) base.SetPosition(); 
    } 
} 

var tree = new Tree { Inner = new ClientGameObject() }; 
tree.SetPosition(); 

SharedLibrary:

public class GameObject 
{ 
    public virtual void SetPosition() { Console.WriteLine("GameObject.SetPosition"); } 
    public static event Func<GameObject> Factory; 
    internal static GameObject CreateBase() { var factory = Factory; return (factory != null) ? factory() : new GameObject(); } 
} 

internal class GameObjectBase : GameObject 
{ 
    private readonly GameObject baseGameObject; 
    protected GameObjectBase() { baseGameObject = GameObject.CreateBase(); } 
    public override void SetPosition() { baseGameObject.SetPosition(); } 
} 

internal class Tree : GameObjectBase 
{ 
    public override void SetPosition() 
    { 
     Console.WriteLine("Tree.SetPosition"); 
     base.SetPosition(); 
    } 
} 

public static class Game 
{ 
    public static void Start() 
    { 
     new Tree().SetPosition(); 
    } 
} 

ClientLibrary:

internal class ClientGameObject : GameObject 
{ 
    public override void SetPosition() 
    { 
     Console.WriteLine("ClientGameObject.SetPosition Before"); 
     base.SetPosition(); 
     Console.WriteLine("ClientGameObject.SetPosition After"); 
    } 
} 

internal static class Program 
{ 
    static void Main(string[] args) 
    { 
     GameObject.Factory +=() => new ClientGameObject(); 
     Game.Start(); 
    } 
} 
+0

我明白你的建議,但我的困境是GameObject的實例和所有繼承它的事物都是在SharedLibrary命名空間中定義,包含和處理的。 ClientProj和ServerProj大部分只處理網絡,用戶和輸入/輸出。因此將對象定義拉出並放入ClientProj幾乎是不可能的,因此您的建議可以實現。 – Arachin 2012-04-24 11:09:57

+0

我並不是建議將SharedLibrary中的'Tree'移動到ClientProj中。你想'樹'是'內部'還是有什麼問題? – dtb 2012-04-24 11:17:37

+0

'Tree'對象只能從'SharedLibrary'內部實例化,因此客戶端覆蓋超出了它的範圍。 – Arachin 2012-04-24 11:35:25

1

使SetPosition方法變爲虛擬並使用override關鍵字來覆蓋其在ClientProj中的行爲。

+0

我看你在暗示什麼,但爲了讓ClientProj命名空間覆蓋所有原始的GameObject實例,需要在幾乎整個庫中覆蓋... 例如:public class Asteroid:GameObject ...我們添加:public class ClientAsteroid:ClientGameObject 如果可能,我想避免這種情況。 – Arachin 2012-04-24 10:55:24

1

您可以在基類中執行virtual,在derived中覆蓋,並在overriden方法中調用您的方法並調用base類的方法。

一個psudocode可以是這樣的:

public class GameObject 
{ 
    public virtual void SetPosition() 
    { 
     //do something here 
    } 
} 


public class Derived: GameObject 
{ 
    public override void SetPosition() 
    { 
     // do something specific to Derived 
     base.SetPosition(); // CALL BASE CLASS METHOD AFTER 
    } 
}