언어

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 + second 에서 firstsecond 파생 DynamicObjectbinder.Operation 된 문의 경우 .ExpressionType.Add

arg
Object

이진 작업에 적합한 피연산자입니다. 예를 들어 클래스 sum = first + second 에서 firstsecond 파생 DynamicObjectarg 된 문의 경우는 같습니다second.

result
Object

이진 작업의 결과입니다.

반품

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

예제

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

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

이 예제에서는 더하기 및 빼기 작업만 지원됩니다. 같은 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 되는 경우 클래스에서 sum = first + second 파생되는 예 multiply = first*second 또는 firstDynamicObject 같은 문에 대해 메서드가 자동으로 호출됩니다.

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

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

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

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

적용 대상