2012-04-24 51 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 
    } 
}