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 文章中记录,添加操作具有以下描述:

一个没有溢出检查的加法运算,用于数字操作数

binder 已经知道如何连接字符串。所需要做的就是将您的 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 回答