根据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。
答案 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
赋值语句。