4

私はこのデリゲート + ハンドラーの新しいことに苦労しています。それは私にとって正しい解決策のようですが、すべてを結びつけることはできません。

私が達成したいことを説明するために最善を尽くします。

まず、私は .NET 4.0 Framework + Photon Server (マルチプレイヤー ゲーム用) を使用しています (答えるのに Photon の経験は必要ありません)。

つまり、実際に今起こっていることは、クライアント (ゲーム) が操作をサーバーに送信することです。これを認識し、受信した操作コードに従ってサーバー上の特定の関数を呼び出す必要があります。

現在の様子は次のとおりです。

switch (operationRequest.OperationCode)
        {
            case 1:
                if (operationRequest.Parameters.ContainsKey(1))
                {
                    Log.Debug("Received: " + operationRequest.Parameters[1]);

                    OperationResponse response = new OperationResponse(operationRequest.OperationCode);
                    response.Parameters = new Dictionary<byte, object> {{1, "Response Received"}};
                    SendOperationResponse(response, sendParameters);
                    Flush();
                }
                break;
        }

これは実際に私にとってはうまくいきます。しかし、200 以上の操作コードが存在することは確実です。全部切り替えるのはもったいないので、そのオペレーションコードに割り当てられた関数(ハンドラ)を呼び出したほうがいいです。

私の知る限り、ここでデリゲートが便利です。

「byte、Handler」を格納する辞書が欲しい

 where "byte" is operation code

 where "Handler" is a delegate to the function

私が推測するようなもの:

byte operationCode = operationRequest.OperationCode; 

if(dictionary.ContainsKey((operaionCode)) {
    dictionary[operationCode](someArguments);
}

この時点から、私は完全に混乱しています。

そのようなディクショナリの作成方法、ハンドラーの作成方法、それらを別のクラスに格納することを前提として、それらを委任してディクショナリに格納する方法。

これは私の友人が私に提案したことです(そして、1週間消えたので、もう一度彼に尋ねることはできません).

  1. 辞書を作成する

    Dictionary<byte, name> = new Dictionary<byte, name>();
    
  2. その辞書にハンドラーを追加します

    dict.Add(operationCode, MoveUnit);
    
  3. デリゲートの初期化 (どこで!?)

    ???
    
  4. ハンドラーを定義する

    private void MoveUnit(SendParameters sendParameter) {...}
    

万が一誰かがアイデアを思いついたら、私を助けてください。

これを読むために時間を費やしてくれた皆さんに感謝します。:|

4

1 に答える 1

3

すべてのメソッドが を受け取ると仮定すると、次のSendParametersことが本当に必要になります。

private static readonly Dictionary<int, Action<SendParameters>> Actions = 
    new Dictionary<int, Action<SendParameters>>
{
    { 1, MoveUnit },
    { 2, AttackUnit }
};

...

static void HandleRequest(Request request)
{
    Action<SendParameters> action;
    if (Actions.TryGetValue(request.OperationCode, out action))
    {
        action(request.Parameters);
    }
}

static void MoveUnit(SendParameters parameters)
{
}

static void AttackUnit(SendParameters parameters)
{
}

インスタンス メソッドの場合は少し複雑になります。静的ディクショナリはインスタンスについて認識しないため、アクションインスタンスを取得させるのが理にかなっている場合があります。というクラスでこれを想定すると、次のFooようなものが必要になる場合があります。

private static readonly Dictionary<int, Action<Foo, SendParameters>> Actions = 
    new Dictionary<int, Action<Foo, SendParameters>>
{
    { 1, (foo, parameters) => foo.MoveUnit(parameters) },
    { 2, (foo, parameters) => foo.AttackUnit(parameters) }
};

private void MoveUnit(SendParameters parameters)
{
}

確かに、それは少し醜いです...最初のパラメーターとして暗黙的に「this」を取るデリゲートを構築できるようにしたいのです。それを行う方法はありますが、もう少し複雑です。

于 2012-05-29T20:18:08.840 に答える