DynamicObject.TryBinaryOperation 方法
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
提供二進位運算的實作。 從該 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 ,其中 first 和 second 是從類別 DynamicObject 推導出來的,則回 binder.Operation 傳 ExpressionType.Add。
- arg
- Object
二進位運算的正確運算元。 例如,對於陳述 sum = first + second ,其中 first 和 second 從 DynamicObject 類別推導出來, 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類別衍生出來。
你可以透過參數 Operation 的 binder 性質來獲得二元運算的類型資訊。
如果你的動態物件只在 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 | b |
a Or b |
OrAssign |
位元或邏輯 OR 複合指派。 |
a |= 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) 和 AndAlso (a && b) 操作,你可能需要同時TryUnaryOperation實作方法和方法。TryBinaryOperation
該 OrElse 運算包含一元 IsTrue 運算與二元 Or 運算。
Or只有當運算結果IsTrue為 false時才會執行。
該 AndAlso 運算包含一元 IsFalse 運算與二元 And 運算。
And只有當運算結果IsFalse為 false時才會執行。