DynamicObject.TryUnaryOperation(UnaryOperationBinder, Object) メソッド

定義

単項演算の実装を提供します。 DynamicObject クラスから派生したクラスは、このメソッドをオーバーライドして、否定、インクリメント、デクリメントなどの操作の動的な動作を指定できます。

public:
 virtual bool TryUnaryOperation(System::Dynamic::UnaryOperationBinder ^ binder, [Runtime::InteropServices::Out] System::Object ^ % result);
public virtual bool TryUnaryOperation(System.Dynamic.UnaryOperationBinder binder, out object result);
abstract member TryUnaryOperation : System.Dynamic.UnaryOperationBinder * obj -> bool
override this.TryUnaryOperation : System.Dynamic.UnaryOperationBinder * obj -> bool
Public Overridable Function TryUnaryOperation (binder As UnaryOperationBinder, ByRef result As Object) As Boolean

パラメーター

binder
UnaryOperationBinder

単項演算に関する情報を提供します。 binder.Operation プロパティは、ExpressionType オブジェクトを返します。 たとえば、DynamicObject クラスから派生numbernegativeNumber = -numberステートメントの場合、binder.Operationは "Negate" を返します。

result
Object

単項演算の結果。

返品

操作が正常に終了した場合は true。それ以外の場合は false。 このメソッドが falseを返す場合、言語のランタイム バインダーによって動作が決定されます。 (ほとんどの場合、言語固有のランタイム例外がスローされます)。

数値のテキスト表現と数値表現を格納するためのデータ構造が必要であり、そのようなデータの数学的否定演算を定義する必要があるとします。

次のコード例は、DynamicNumber クラスから派生したDynamicObject クラスを示しています。 DynamicNumber は、数学的否定演算を有効にするために TryUnaryOperation メソッドをオーバーライドします。 また、 TrySetMember メソッドと TryGetMember メソッドをオーバーライドして、要素へのアクセスを有効にします。

この例では、数学的否定演算のみがサポートされています。 negativeNumber = +numberなどのステートメントを記述しようとすると、実行時例外が発生します。

// 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 unary operation.
    public override bool TryUnaryOperation(
        UnaryOperationBinder binder, out object result)
    {
        // The Textual property contains
        // the name of the unary operation in addition
        // to the textual representaion of the number.
        string resultTextual =
             binder.Operation + " " +
             dictionary["Textual"].ToString();
        int resultNumeric;

        // Determining what type of operation is being performed.
        switch (binder.Operation)
        {
            case ExpressionType.Negate:
                resultNumeric =
                     -(int)dictionary["Numeric"];
                break;
            default:
                // In case of any other unary 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 +
                    ": This unary 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 number = new DynamicNumber();

        // Creating properties and setting their values
        // for the dynamic number.
        // The TrySetMember method is called.
        number.Textual = "One";
        number.Numeric = 1;

        // Printing out properties. The TryGetMember method is called.
        Console.WriteLine(
            number.Textual + " " + number.Numeric);

        dynamic negativeNumber = new DynamicNumber();

        // Performing a mathematical negation.
        // TryUnaryOperation is called.
        negativeNumber = -number;

        Console.WriteLine(
            negativeNumber.Textual + " " + negativeNumber.Numeric);

        // The following statement produces a run-time exception
        // because the unary plus operation is not implemented.
        // negativeNumber = +number;
    }
}

// This code example produces the following output:

// One 1
// Negate One -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 unary operation. 
    Public Overrides Function TryUnaryOperation(
        ByVal binder As System.Dynamic.UnaryOperationBinder,
        ByRef result As Object) As Boolean

        ' The Textual property contains the name of the unary operation
        ' in addition to the textual representaion of the number.
        Dim resultTextual As String =
        binder.Operation.ToString() & " " &
        dictionary("Textual")
        Dim resultNumeric As Integer

        ' Determining what type of operation is being performed.
        Select Case binder.Operation
            Case ExpressionType.Negate
                resultNumeric = -CInt(dictionary("Numeric"))
            Case Else
                ' In case of any other unary 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 unary 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 number As Object = New DynamicNumber()

    ' Creating properties and setting their values
    ' for the dynamic number.
    ' The TrySetMember method is called.
    number.Textual = "One"
    number.Numeric = 1

    ' Printing out properties. The TryGetMember method is called.
    Console.WriteLine(
        number.Textual & " " & number.Numeric)

    Dim negativeNumber As Object = New DynamicNumber()

    ' Performing a mathematical negation.
    ' The TryUnaryOperation is called.
    negativeNumber = -number

    Console.WriteLine(
        negativeNumber.Textual & " " & negativeNumber.Numeric)

    ' The following statement produces a run-time exception
    ' because the unary plus operation is not implemented.
    'negativeNumber = +number
End Sub

' This code example produces the following output:

' One 1
' Negate One -1

注釈

DynamicObject クラスから派生したクラスは、このメソッドをオーバーライドして、動的オブジェクトに対して単項演算を実行する方法を指定できます。 メソッドがオーバーライドされない場合、言語のランタイム バインダーによって動作が決まります。 (ほとんどの場合、言語固有のランタイム例外がスローされます)。

このメソッドは、否定、インクリメント、デクリメントなどの単項演算がある場合に呼び出されます。 たとえば、 TryUnaryOperation メソッドがオーバーライドされた場合、このメソッドは、 negativeNumber = -numberなどのステートメントに対して自動的に呼び出されます。ここで、 numberDynamicObject クラスから派生します。

単項演算の型に関する情報は、binder パラメーターの Operation プロパティを使用して取得できます。

動的オブジェクトが C# および Visual Basic でのみ使用されている場合、binder.Operation プロパティには、ExpressionType 列挙体の次のいずれかの値を指定できます。 ただし、IronPython や IronRuby などの他の言語では、他の値を持つことができます。

価値 説明 C# Visual Basic
Decrement 単項デクリメント操作。 a-- サポートされていません。
Increment 単項インクリメント操作。 a++ サポートされていません。
Negate 算術否定。 -a -a
Not 論理否定。 !a Not a
OnesComplement 1 は補数です。 ~a サポートされていません。
IsFalse false 条件値。 a && b サポートされていません。
IsTrue 真の条件値。 a &#124;&#124; b サポートされていません。
UnaryPlus 単項プラス。 +a +a

Note

C# で動的オブジェクトの OrElse (a || b) および AndAlso (a && b) 操作を実装するには、 TryUnaryOperation メソッドと TryBinaryOperation メソッドの両方を実装する必要があります。

OrElse操作は、単項IsTrue操作とバイナリ Or操作で構成されます。 Or操作は、IsTrue操作の結果がfalseされた場合にのみ実行されます。

AndAlso操作は、単項IsFalse操作とバイナリ And操作で構成されます。 And操作は、IsFalse操作の結果がfalseされた場合にのみ実行されます。

適用対象