DynamicObject二进制操作的绑定行为因操作符和操作数而异

时间:2014-04-26 15:03:03

标签: c# .net dynamic-language-runtime binary-operators

根据TryBinaryOperation的文档,当二进制操作的左侧是动态对象时,将调用此方法。

我有一个派生自动态对象的类,我发现并不总是如此。对于这个例子,我希望对我的覆盖TryBinaryOperation进行3次调用,但只获得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。

1 个答案:

答案 0 :(得分:7)

 dynamic d1 = d + "add it";

这不是二进制操作,即字符串连接。在DynamicObject.TryBinaryOperation()的MSDN文章中记录, Add 操作具有以下描述:

  

无溢出检查的加法运算,表示数字操作数

绑定器已经知道如何连接字符串。所需的只是将DynamicObject转换为字符串。您可以通过添加ToString()覆盖来看到:

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

在它上面设置一个断点,并在断开时查看调用堆栈:

  

ConsoleApplication327.exe!ConsoleApplication327.MyDynamic.ToString()第22行C#       mscorlib.dll!string.Concat(对象arg0,对象arg1)+ 0x1e字节
      System.Core.dll!System.Dynamic.UpdateDelegates.UpdateAndExecute2(System.Runtime.CompilerServices.CallSite site,object arg0,string arg1)+ 0x2ae bytes
      ConsoleApplication327.exe!ConsoleApplication327.Program.Main(string [] args)第30行+ 0x146字节C#

第30行是我测试程序中的d1赋值语句。