2

TryBinaryOperationのドキュメントによると、このメソッドは、二項演算の左側が動的オブジェクトの場合に呼び出されます。

動的オブジェクトから派生したクラスを持っていますが、常にそうであるとは限りません。この例では、オーバーライドへの 3 つの呼び出しが予想されますTryBinaryOperationが、取得されるのは 2 つだけです。

public class MyDynamic : DynamicObject
{
    public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result)
    {
        Console.WriteLine("operation = " + binder.Operation.ToString());
        result = arg;
        return true;
    }
}

class Program
{
    static void Main(string[] args)
    {           
        dynamic d = new MyDynamic();

        dynamic d1 = d + "add it";
        dynamic d2 = d + 1;
        dynamic d3 = d >> "shift it";

        Console.WriteLine("");

        Console.WriteLine(d1);
        Console.WriteLine(d2);
        Console.WriteLine(d3);
    }
}

ただし、最初の呼び出しでは文字列 " DynamicRestProxy.UnitTests.MyDynamicadd it" が返されます。つまりd.ToString() + "add it"、動的クラスのバイナリ操作を試みる代わりに、加算演算子によって呼び出されています。さらに、「+」の右側の演算子が int の場合、動的操作が試行されます。

上記のプログラムの出力は次のとおりです (呼び出しd + "add it"が に到達しないことに注意してTryBinaryOperationください)。

operation = Add
operation = RightShift

DynamicRestProxy.UnitTests.MyDynamicadd it
1
shift it

どこにあると思いますか

operation = Add
operation = Add
operation = RightShift

add it
1
shift it

これは正しい予想される動作ですか? もしそうなら、説明するドキュメントはどこかにありますか?

これは VS.NET 2013 と .NET 4.5 を使用しています。

4

1 に答える 1

7
 dynamic d1 = d + "add it";

これは二項演算ではなく、文字列連結です。DynamicObject.TryBinaryOperation() の MSDN 記事に記載されている追加操作には、次の説明があります。

数値オペランドのオーバーフロー チェックなしの加算演算。

バインダーは、文字列を連結する方法を既に知っています。必要なのは、DynamicObject を文字列に変換することだけです。ToString() オーバーライドを追加することで確認できます。

    public override string ToString() {
        return base.ToString();
    }

それにブレークポイントを設定し、ブレークしたときにコール スタックを確認します。

ConsoleApplication327.exe!ConsoleApplication327.MyDynamic.ToString() 行 22 C# mscorlib.dll!string.Concat(object arg0, object arg1) + 0x1e バイト
System.Core.dll!System.Dynamic.UpdateDelegates.UpdateAndExecute2(System.Runtime.CompilerServices .CallSite サイト、オブジェクト arg0、文字列 arg1) + 0x2ae バイト
ConsoleApplication327.exe!ConsoleApplication327.Program.Main(string[] args) 30 行目 + 0x146 バイト C#

30 行目はd1、テスト プログラムの割り当てステートメントです。

于 2014-04-29T13:40:29.617 に答える