DynamicObject.TryBinaryOperation 方法    
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
提供二元运算的实现。 从 DynamicObject 类派生的类可以重写此方法,以便为诸如加法和乘法这样的运算指定动态行为。
public:
 virtual bool TryBinaryOperation(System::Dynamic::BinaryOperationBinder ^ binder, System::Object ^ arg, [Runtime::InteropServices::Out] System::Object ^ % result);public virtual bool TryBinaryOperation (System.Dynamic.BinaryOperationBinder binder, object arg, out object result);public virtual bool TryBinaryOperation (System.Dynamic.BinaryOperationBinder binder, object arg, out object? result);abstract member TryBinaryOperation : System.Dynamic.BinaryOperationBinder * obj * obj -> bool
override this.TryBinaryOperation : System.Dynamic.BinaryOperationBinder * obj * obj -> boolPublic Overridable Function TryBinaryOperation (binder As BinaryOperationBinder, arg As Object, ByRef result As Object) As Boolean参数
- binder
- BinaryOperationBinder
提供有关二元运算的信息。 属性 binder.Operation 返回 对象 ExpressionType 。 例如,对于 sum = first + second 从 类派生的 DynamicObject 和 second 的 语句first,binder.Operation返回 ExpressionType.Add。
- arg
- Object
二元运算的右操作数。 例如,对于 sum = first + second 从 类派生的 DynamicObject 和 second 的 语句first,arg等于 second。
- result
- Object
二元运算的结果。
返回
如果操作成功,则为 true;否则为 false。 如果此方法返回 false,则该语言的运行时联编程序将决定行为。 (大多数情况下,将引发语言特定的运行时异常。)
示例
假设需要一个数据结构来存储数字的文本和数字表示形式,并且想要定义基本数学运算,例如此类数据的加法和减法。
下面的代码示例演示 DynamicNumber 派生自 类的 DynamicObject 类。 
              DynamicNumber 重写 方法以 TryBinaryOperation 启用数学运算。 它还重写 TrySetMember 和 TryGetMember 方法,以启用对元素的访问。
在此示例中,仅支持加法和减法运算。 如果尝试编写类似 的 resultNumber = firstNumber*secondNumber语句,则会引发运行时异常。
// Add using System.Linq.Expressions;
// to the beginning of the file.
// The class derived from DynamicObject.
public class DynamicNumber : DynamicObject
{
    // The inner dictionary to store field names and values.
    Dictionary<string, object> dictionary
        = new Dictionary<string, object>();
    // Get the property value.
    public override bool TryGetMember(
        GetMemberBinder binder, out object result)
    {
        return dictionary.TryGetValue(binder.Name, out result);
    }
    // Set the property value.
    public override bool TrySetMember(
        SetMemberBinder binder, object value)
    {
        dictionary[binder.Name] = value;
        return true;
    }
    // Perform the binary operation.
    public override bool TryBinaryOperation(
        BinaryOperationBinder binder, object arg, out object result)
    {
        // The Textual property contains the textual representaion
        // of two numbers, in addition to the name
        // of the binary operation.
        string resultTextual =
            dictionary["Textual"].ToString() + " "
            + binder.Operation + " " +
            ((DynamicNumber)arg).dictionary["Textual"].ToString();
        int resultNumeric;
        // Checking what type of operation is being performed.
        switch (binder.Operation)
        {
            // Proccessing mathematical addition (a + b).
            case ExpressionType.Add:
                resultNumeric =
                    (int)dictionary["Numeric"] +
                    (int)((DynamicNumber)arg).dictionary["Numeric"];
                break;
            // Processing mathematical substraction (a - b).
            case ExpressionType.Subtract:
                resultNumeric =
                    (int)dictionary["Numeric"] -
                    (int)((DynamicNumber)arg).dictionary["Numeric"];
                break;
            // In case of any other binary operation,
            // print out the type of operation and return false,
            // which means that the language should determine
            // what to do.
            // (Usually the language just throws an exception.)
            default:
                Console.WriteLine(
                    binder.Operation +
                    ": This binary operation is not implemented");
                result = null;
                return false;
        }
        dynamic finalResult = new DynamicNumber();
        finalResult.Textual = resultTextual;
        finalResult.Numeric = resultNumeric;
        result = finalResult;
        return true;
    }
}
class Program
{
    static void Test(string[] args)
    {
        // Creating the first dynamic number.
        dynamic firstNumber = new DynamicNumber();
        // Creating properties and setting their values
        // for the first dynamic number.
        // The TrySetMember method is called.
        firstNumber.Textual = "One";
        firstNumber.Numeric = 1;
        // Printing out properties. The TryGetMember method is called.
        Console.WriteLine(
            firstNumber.Textual + " " + firstNumber.Numeric);
        // Creating the second dynamic number.
        dynamic secondNumber = new DynamicNumber();
        secondNumber.Textual = "Two";
        secondNumber.Numeric = 2;
        Console.WriteLine(
            secondNumber.Textual + " " + secondNumber.Numeric);
        dynamic resultNumber = new DynamicNumber();
        // Adding two numbers. The TryBinaryOperation is called.
        resultNumber = firstNumber + secondNumber;
        Console.WriteLine(
            resultNumber.Textual + " " + resultNumber.Numeric);
        // Subtracting two numbers. TryBinaryOperation is called.
        resultNumber = firstNumber - secondNumber;
        Console.WriteLine(
            resultNumber.Textual + " " + resultNumber.Numeric);
        // The following statement produces a run-time exception
        // because the multiplication operation is not implemented.
        // resultNumber = firstNumber * secondNumber;
    }
}
// This code example produces the following output:
// One 1
// Two 2
// One Add Two 3
// One Subtract Two -1
' Add Imports System.Linq.Expressions
' to the beginning of the file.
' The class derived from DynamicObject.
Public Class DynamicNumber
    Inherits DynamicObject
    ' The inner dictionary to store field names and values.
    Dim dictionary As New Dictionary(Of String, Object)
    ' Get the property value.
    Public Overrides Function TryGetMember(
        ByVal binder As System.Dynamic.GetMemberBinder,
        ByRef result As Object) As Boolean
        Return dictionary.TryGetValue(binder.Name, result)
    End Function
    ' Set the property value.
    Public Overrides Function TrySetMember(
        ByVal binder As System.Dynamic.SetMemberBinder,
        ByVal value As Object) As Boolean
        dictionary(binder.Name) = value
        Return True
    End Function
    ' Perform the binary operation. 
    Public Overrides Function TryBinaryOperation(
        ByVal binder As System.Dynamic.BinaryOperationBinder,
        ByVal arg As Object, ByRef result As Object) As Boolean
        ' The Textual property contains the textual representaion 
        ' of two numbers, in addition to the name of the binary operation.
        Dim resultTextual As String =
            dictionary("Textual") & " " &
            binder.Operation.ToString() & " " &
        CType(arg, DynamicNumber).dictionary("Textual")
        Dim resultNumeric As Integer
        ' Checking what type of operation is being performed.
        Select Case binder.Operation
            ' Proccessing mathematical addition (a + b).
            Case ExpressionType.Add
                resultNumeric =
                CInt(dictionary("Numeric")) +
                CInt((CType(arg, DynamicNumber)).dictionary("Numeric"))
                ' Processing mathematical substraction (a - b).
            Case ExpressionType.Subtract
                resultNumeric =
                CInt(dictionary("Numeric")) -
                CInt((CType(arg, DynamicNumber)).dictionary("Numeric"))
            Case Else
                ' In case of any other binary operation,
                ' print out the type of operation and return false,
                ' which means that the language should determine 
                ' what to do.
                ' (Usually the language just throws an exception.)
                Console.WriteLine(
                    binder.Operation.ToString() &
                    ": This binary operation is not implemented")
                result = Nothing
                Return False
        End Select
        Dim finalResult As Object = New DynamicNumber()
        finalResult.Textual = resultTextual
        finalResult.Numeric = resultNumeric
        result = finalResult
        Return True
    End Function
End Class
Sub Test()
    ' Creating the first dynamic number.
    Dim firstNumber As Object = New DynamicNumber()
    ' Creating properties and setting their values
    ' for the first dynamic number. 
    ' The TrySetMember method is called.
    firstNumber.Textual = "One"
    firstNumber.Numeric = 1
    ' Printing out properties. The TryGetMember method is called.
    Console.WriteLine(
        firstNumber.Textual & " " & firstNumber.Numeric)
    ' Creating the second dynamic number.
    Dim secondNumber As Object = New DynamicNumber()
    secondNumber.Textual = "Two"
    secondNumber.Numeric = 2
    Console.WriteLine(
        secondNumber.Textual & " " & secondNumber.Numeric)
    Dim resultNumber As Object = New DynamicNumber()
    ' Adding two numbers. TryBinaryOperation is called.
    resultNumber = firstNumber + secondNumber
    Console.WriteLine(
        resultNumber.Textual & " " & resultNumber.Numeric)
    ' Subtracting two numbers. TryBinaryOperation is called.
    resultNumber = firstNumber - secondNumber
    Console.WriteLine(
        resultNumber.Textual & " " & resultNumber.Numeric)
    ' The following statement produces a run-time exception
    ' because the multiplication operation is not implemented.
    ' resultNumber = firstNumber * secondNumber
End Sub
' This code example produces the following output:
' One 1
' Two 2
' One Add Two 3
' One Subtract Two -1
注解
派生自 类的 DynamicObject 类可以重写此方法,以指定应如何对动态对象执行二进制操作。 当方法未重写时,语言的运行时绑定器将确定行为。 (大多数情况下,将引发语言特定的运行时异常。)
当具有二进制运算(例如加法或乘法)时,将调用此方法。 例如,如果TryBinaryOperation重写了 方法,则会自动为 或 multiply = first*second等sum = first + second语句调用该方法,其中first派生自 DynamicObject 类。
可以使用 参数的 属性binder获取有关二进制操作Operation类型的信息。
如果动态对象仅在 C# 和 Visual Basic 中使用,则 binder.Operation 属性可以从枚举中 ExpressionType 具有以下值之一。 但是,在其他语言(如 IronPython 或 IronRuby)中,可以具有其他值。
| “值” | 说明 | C# | Visual Basic | 
|---|---|---|---|
| Add | 不进行溢出检查的加法运算,用于数字操作数。 | a + b | a + b | 
| AddAssign | 不进行溢出检查的加法复合赋值运算,用于数字操作数。 | a += b | 不支持。 | 
| And | 按位 AND运算。 | a & b | a And b | 
| AndAssign | 按位 AND复合赋值运算。 | a &= b | 不支持。 | 
| Divide | 算术除法运算。 | a / b | a / b | 
| DivideAssign | 算术除法复合赋值运算。 | a /= b | 不支持。 | 
| ExclusiveOr | 按位 XOR运算。 | a ^ b | a Xor b | 
| ExclusiveOrAssign | 按位 XOR复合赋值运算。 | a ^= b | 不支持。 | 
| GreaterThan | “大于”比较。 | a > b | a > b | 
| GreaterThanOrEqual | “大于或等于”比较。 | a >= b | 不支持。 | 
| LeftShift | 按位左移运算。 | a << b | a << b | 
| LeftShiftAssign | 按位左移复合赋值运算。 | a <<= b | 不支持。 | 
| LessThan | “小于”比较。 | a < b | a < b | 
| LessThanOrEqual | “小于或等于”比较。 | a <= b | 不支持。 | 
| Modulo | 算术余数运算。 | a % b | a Mod b | 
| ModuloAssign | 算术余数复合赋值运算。 | a %= b | 不支持。 | 
| Multiply | 对于数值操作数,无需溢出检查的乘法运算。 | a * b | a * b | 
| MultiplyAssign | 对于数值操作数,无需溢出检查的乘法复合赋值运算。 | a *= b | 不支持。 | 
| NotEqual | 不相等比较。 | a != b | a <> b | 
| Or | 按位运算或逻辑 OR运算。 | a | b | a Or b | 
| OrAssign | 按位或逻辑 OR复合赋值。 | a |= b | 不支持。 | 
| Power | 将数字提高到幂的数学运算。 | 不支持。 | a ^ b | 
| RightShift | 按位右移运算。 | a >> b | a >> b | 
| RightShiftAssign | 按位右移复合赋值运算。 | a >>= b | 不支持。 | 
| Subtract | 不进行溢出检查的减法运算,用于数字操作数。 | a - b | a - b | 
| SubtractAssign | 对于数值操作数,无需溢出检查的减法复合赋值运算。 | a -= b | 不支持。 | 
备注
若要在 C# 中实现 OrElse (a || b) 和 AndAlso (a && b) 操作,可能需要同时 TryUnaryOperation 实现 方法和 TryBinaryOperation 方法。
该 OrElse 操作由一元 IsTrue 运算和二进制 Or 运算组成。 
              Or仅当操作的结果为 false时,IsTrue才会执行该操作。
该 AndAlso 操作由一元 IsFalse 运算和二进制 And 运算组成。 
              And仅当操作的结果为 false时,IsFalse才会执行该操作。