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);
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 + secondfirstsecond 클래스 binder.Operation 에서 DynamicObject 파생되는 문의 경우 은 를 반환합니다.ExpressionType.Add

arg
Object

이항 연산의 오른쪽 피연산자입니다. 예를 들어 sum = first + second 클래스에서 DynamicObjectarg 파생된 및 second 가 인 문의 first 경우 는 와 같습니다second.

result
Object

이항 연산의 결과입니다.

반환

작업에 성공하면 true이고, 그렇지 않으면 false입니다. 이 메서드가 false를 반환하는 경우 언어의 런타임 바인더에 따라 동작이 결정됩니다. 대부분의 경우 언어별 런타임 예외가 throw됩니다.

예제

숫자의 텍스트 및 숫자 표현을 저장하기 위해 데이터 구조가 필요하다고 가정하고 이러한 데이터에 대한 추가 및 빼기와 같은 기본 수학 연산을 정의하려고 합니다.

다음 코드 예제에서는 DynamicNumber 클래스에서 파생 되는 클래스를 보여 줍니다 DynamicObject . DynamicNumber 는 메서드를 재정의 TryBinaryOperation 하여 수학 연산을 사용하도록 설정합니다. 또한 및 TryGetMember 메서드를 재정의 TrySetMember 하여 요소에 액세스할 수 있도록 합니다.

이 예제에서는 추가 및 빼기 작업만 지원됩니다. 와 같은 resultNumber = firstNumber*secondNumber문을 작성하려고 하면 런타임 예외가 throw됩니다.

// 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 하여 동적 개체에 대해 이진 작업을 수행하는 방법을 지정할 수 있습니다. 메서드를 재정의하지 않으면 언어의 런타임 바인더가 동작을 결정합니다. 대부분의 경우 언어별 런타임 예외가 throw됩니다.

이 메서드는 더하기 또는 곱하기와 같은 이진 작업이 있을 때 호출됩니다. 예를 들어 메서드가 재정의 TryBinaryOperation 되면 또는 multiply = first*second와 같은 sum = first + second 문에 대해 자동으로 호출됩니다. 여기서 first 는 클래스에서 DynamicObject 파생됩니다.

매개 변수의 속성을 binder 사용하여 Operation 이진 작업의 형식에 대한 정보를 가져올 수 있습니다.

동적 개체가 C# 및 Visual Basic에서만 사용되는 경우 속성은 binder.Operation 열거형의 ExpressionType 다음 값 중 하나를 가질 수 있습니다. 그러나 IronPython 또는 IronRuby와 같은 다른 언어에서는 다른 값을 가질 수 있습니다.

Description 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 지원되지 않습니다.

참고

C#에서 동적 개체에 대한 (a || b) 및 AndAlso (a && b) 작업을 구현 OrElse 하려면 메서드와 TryBinaryOperation 메서드를 TryUnaryOperation 모두 구현할 수 있습니다.

작업은 OrElse 단항 IsTrue 연산과 이진 Or 작업으로 구성됩니다. Or 작업은 작업의 결과가 IsTrue 인 경우에만 수행됩니다false.

작업은 AndAlso 단항 IsFalse 연산과 이진 And 작업으로 구성됩니다. And 작업은 작업의 결과가 IsFalse 인 경우에만 수행됩니다false.

적용 대상