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);
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 返します。 たとえば、 negativeNumber = -number クラスからDynamicObject派生した ステートメントnumberの場合、 binder.Operation は "Negate" を返します。

result
Object

単項演算の結果。

戻り値

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

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

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

この例では、数学的否定演算のみがサポートされています。 のような 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 true 条件値。 a &#124;&#124; b サポートされていません。
UnaryPlus 単項プラス。 +a +a

注意

C# で動的オブジェクトに対して (a || b) 操作と AndAlso (a && b) 操作を実装OrElseするには、 メソッドと メソッドの両方をTryBinaryOperationTryUnaryOperation実装できます。

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

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

適用対象