6

誰かがdynamicメソッド呼び出し(特にRuntimeBinderExceptionsを上げる予定の呼び出し)をインターセプトする方法を知っていRealProxyますか?私は例外をキャッチし、その上に「メソッドがありません」を実装することを望んでいましたが、インターセプターがルックインを取得する前にスローされたようです。

私のテストは次のようになります。

dynamic hello = MethodMissingInterceptor<DynamicObject>.Create();
Assert.AreEqual("World", hello.World());

Worldに実際に実装されていない場所DynamicObjectIMethodReturnMessage.Exceptionインターセプターは非常に単純です-私は次のようなものをチェックしRuntimeBinderExceptionて転送することを望んでいました:

public IMessage MethodMissing(IMethodCallMessage call)
{
    return new ReturnMessage(call.MethodBase.Name, new object[0], 0, call.LogicalCallContext, call);
}

残念ながら、インターセプターに表示されるのは、への呼び出しGetTypeだけであり、存在しないWorldメソッドではありません。

DynamicProxyそれが失敗した場合-.NET4.0で正常に実行されているバージョンがあるかどうかを誰かが知っていますが、それでも問題に対処できた可能性がありますか?

4

1 に答える 1

17

長い答えから始めましょう。C# での動的操作のすべてのバインドは、およそ次の 3 つのことをこの順序で実行します。

  1. オブジェクトが IDynamicMetaObjectProvider を実装しているか、COM オブジェクトであるかをバインドするようオブジェクトに要求し、それが失敗した場合は...
  2. リフレクションを使用して操作をプレーン オールド clr オブジェクトの操作にバインドし、それが失敗した場合は...
  3. バインドの完全な失敗を表す DynamicMetaObject を返します。

GetType 呼び出しが表示されているのは、ステップ 2 で、呼び出しに適した "World" メソッドがあるかどうかを確認するために C# ランタイム バインダーがユーザーに反映されているためです。あるとすれば、何か特別なことを思いつくことはできませんでした。

残念ながら、RuntimeBinderException がスローされるまでには、バインドされていません。例外は、ステップ 3 で返されたメタ オブジェクトに応答して、動的操作の実行フェーズから発生します。これをキャッチする唯一の機会は、実際の呼び出しサイトにあります。

そのため、C# で method_missing を実装したい場合、その戦略はうまくいきません。ただし、いくつかのオプションがあります。

簡単なオプションの 1 つは、MethodMissingInterceptor に IDynamicMetaObjectProvider を実装し、ラップされたオブジェクトの IDMOP 実装に従うことです。内部 IDMOP の一部で障害が発生した場合は、必要なものにバインドできます (おそらく、インターセプターに格納されている method_missing デリゲートへの呼び出し)。ここでの欠点は、これが動的オブジェクトであることがわかっているオブジェクト、たとえば最初から IDMOP を実装しているオブジェクトに対してのみ機能することです。これは、基本的にステップ 1 と 2 の間に自分自身を挿入しているためです。

私が考えることができる別の代替手段は、IDynamicMetaObjectProvider を実装し、その中ですべてのバインドに積極的に応答し、(a) C# コンパイラが最初にバインドするために生成したコードと同じコードを生成するメソッドへの呼び出しを返すことです。 b) RuntimeBinderException をキャッチして、method_missing メソッドを呼び出します。ここでの欠点は、非常に複雑になることです。C# ランタイム バインダー アセンブリのパブリック型に対して、任意のデリゲート型とそれらを使用する IL を生成する必要があります。しかし、少なくとも、すべての操作に対してメソッドが欠落しているでしょう。

リモートプロキシの使用についてほのめかしているように見えるなど、私が考えていなかった他の戦略があると確信しています。彼らがどのように見えるかは想像できませんし、成功するかどうかもわかりません.

ここでの問題の核心は、C# 4.0 には、これを実行したいというユーザーの要望を予測する設計がないということです。具体的には、ステップ 2 と 3 の間に自分自身を簡単に挿入することはできません。それで、短い答えになります。申し訳ありませんが、C# 4.0 には method_missing がありません。

于 2009-06-10T00:32:49.400 に答える