1

私には2つのプロジェクトがあります:ClientProjと、両方とも私のゲームの基本を含むものをServerProj共有しています。SharedLibrary

このライブラリ内にGameObjectは、他の多くのゲームアイテムが継承する基本クラスであるクラスがあります。

GameObjectにはSetPosition()メソッドがあります。

これが私の問題です。クライアントで実行するときにSetPosition()、コードを追加したり、メソッドを完全にオーバーライドしたりしたいと思います。ただし、追加したいコードは、ClientProj名前空間にのみ存在するクラスに関連しており、名前空間についてはSharedLibrary何も知りません。

ライブラリメソッドをオーバーライドまたは拡張するクリーンな方法はありますか?

更新:GameObjectのインスタンスとそれを継承するすべてのものは、SharedLibrary名前空間内ですべて定義、包含、および処理されることに注意してください。ほとんどの場合、ClientProjとServerProjは、ネットワーク、ユーザー、および入出力のみを処理します。

4

3 に答える 3

3

Proxy パターンを使用して、ゲーム オブジェクトを実際のクラスではなくプロキシ クラスから継承させることができます。

共有ライブラリ:

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

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

public class Tree : DelegatingGameObject
{
}

クライアント ライブラリ:

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

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

共有ライブラリ:

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

クライアント ライブラリ:

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();
    }
}
于 2012-04-24T10:53:06.457 に答える
1

SetPosition メソッドを仮想化し、override キーワードを使用して ClientProj での動作をオーバーライドします。

于 2012-04-24T10:47:16.953 に答える
1

virtual基本クラスでそれを行い、でオーバーライドし、オーバーライドされderivedたメソッドでメソッドを呼び出し、baseクラス メソッドの後に呼び出すことができます。

疑似コードは次のようになります。

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
    }
}
于 2012-04-24T10:47:28.913 に答える