根据 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。
最佳答案
dynamic d1 = d + "add it";
那不是二元运算,那是字符串连接。在 DynamicObject.TryBinaryOperation() 的 MSDN 文章中,Add 操作描述如下:
An addition operation without overflow checking, for numeric operands.
Binder 已经知道如何连接字符串。所需要做的就是将 DynamicObject 转换为字符串。您可以通过添加 ToString() 覆盖来查看:
public override string ToString() {
return base.ToString();
}
在其上设置断点,断点时查看调用栈:
ConsoleApplication327.exe!ConsoleApplication327.MyDynamic.ToString() Line 22 C# mscorlib.dll!string.Concat(object arg0, object arg1) + 0x1e bytes
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) Line 30 + 0x146 bytes C#
第 30 行是我的测试程序中的 d1
赋值语句。
关于c# - DynamicObject 二元运算的绑定(bind)行为因运算符和操作数而异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23312652/