DynamicObject.TryBinaryOperation 方法

定義

提供二進位運算的實作。 從該 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);
abstract member TryBinaryOperation : System.Dynamic.BinaryOperationBinder * obj * obj -> bool
override this.TryBinaryOperation : System.Dynamic.BinaryOperationBinder * obj * obj -> bool
Public Overridable Function TryBinaryOperation (binder As BinaryOperationBinder, arg As Object, ByRef result As Object) As Boolean

參數

binder
BinaryOperationBinder

提供有關二進位操作的資訊。 該屬性回 binder.Operation 傳一個 ExpressionType 物件。 例如,對於陳述 sum = first + second ,其中 firstsecond 是從類別 DynamicObject 推導出來的,則回 binder.OperationExpressionType.Add

arg
Object

二進位運算的正確運算元。 例如,對於陳述 sum = first + second ,其中 firstsecondDynamicObject 類別推導出來, arg 等於 second

result
Object

這是二元運算的結果。

傳回

如果作業成功,則為 true,否則為 false。 若此方法回傳 false,該語言的執行時綁定器決定行為。 (大多數情況下會拋出語言特定的執行時例外。)

範例

假設你需要一個資料結構來儲存數字的文字和數字表示,並且你想定義基本的數學運算,例如加法和減法。

以下程式碼範例展示了 DynamicNumber 由該 DynamicObject 類別衍生而來的類別。 DynamicNumber 覆蓋該 TryBinaryOperation 方法以實現數學運算。 它也會覆蓋 TrySetMember and 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方法被覆寫,則會自動呼叫該方法sum = first + secondmultiply = first*second,例如或 ,其中 first 是從DynamicObject類別衍生出來。

你可以透過參數 Operationbinder 性質來獲得二元運算的類型資訊。

如果你的動態物件只在 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 &#124; b a Or b
OrAssign 位元或邏輯 OR 複合指派。 a &#124;= b 不支援。
Power 一個將數字升為冪的數學運算。 不支援。 a ^ b
RightShift 一個位元右移運算。 a >> b a >> b
RightShiftAssign 一個位元右移複合指派運算。 a >>= b 不支援。
Subtract 一種無溢位檢查的減法運算,用於數值運算元。 a - b a - b
SubtractAssign 一種無溢位檢查的減法複數指派操作,用於數值運算元。 a -= b 不支援。

Note

要在 C# 中實作OrElse動態物件的 (a || b) 和 AndAlsoa && b) 操作,你可能需要同時TryUnaryOperation實作方法和方法。TryBinaryOperation

OrElse 運算包含一元 IsTrue 運算與二元 Or 運算。 Or只有當運算結果IsTruefalse時才會執行。

AndAlso 運算包含一元 IsFalse 運算與二元 And 運算。 And只有當運算結果IsFalsefalse時才會執行。

適用於