DynamicObject 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
提供一個基底類別,用於在執行時指定動態行為。 此類別必須繼承自:你無法直接實例化它。
public ref class DynamicObject : System::Dynamic::IDynamicMetaObjectProvider
public class DynamicObject : System.Dynamic.IDynamicMetaObjectProvider
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Creating a call site may require dynamic code generation.")]
public class DynamicObject : System.Dynamic.IDynamicMetaObjectProvider
[System.Serializable]
public class DynamicObject : System.Dynamic.IDynamicMetaObjectProvider
type DynamicObject = class
interface IDynamicMetaObjectProvider
[<System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Creating a call site may require dynamic code generation.")>]
type DynamicObject = class
interface IDynamicMetaObjectProvider
[<System.Serializable>]
type DynamicObject = class
interface IDynamicMetaObjectProvider
Public Class DynamicObject
Implements IDynamicMetaObjectProvider
- 繼承
-
DynamicObject
- 衍生
- 屬性
- 實作
範例
假設你想提供替代語法來存取字典中的值,這樣你就不用寫 sampleDictionary["Text"] = "Sample text"(Visual Basic 中的 sampleDictionary("Text") = "Sample text"),而是寫成 sampleDictionary.Text = "Sample text"。 此外,你希望這個語法不區分大小寫,所以 sampleDictionary.Text 相當於 sampleDictionary.text。
以下程式碼範例展示了 DynamicDictionary 由該 DynamicObject 類別衍生而來的類別。
DynamicDictionary 類別包含一個 Dictionary<string, object> 型別的物件(Visual Basic 中的 Dictionary(Of String, Object))用來儲存鍵值對,並覆蓋 TrySetMember 和 TryGetMember 方法以支援新的語法。 它也提供一個 Count 性質,顯示字典包含多少動態性質。
// The class derived from DynamicObject.
public class DynamicDictionary : DynamicObject
{
// The inner dictionary.
Dictionary<string, object> dictionary
= new Dictionary<string, object>();
// This property returns the number of elements
// in the inner dictionary.
public int Count
{
get
{
return dictionary.Count;
}
}
// If you try to get a value of a property
// not defined in the class, this method is called.
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
// Converting the property name to lowercase
// so that property names become case-insensitive.
string name = binder.Name.ToLower();
// If the property name is found in a dictionary,
// set the result parameter to the property value and return true.
// Otherwise, return false.
return dictionary.TryGetValue(name, out result);
}
// If you try to set a value of a property that is
// not defined in the class, this method is called.
public override bool TrySetMember(
SetMemberBinder binder, object value)
{
// Converting the property name to lowercase
// so that property names become case-insensitive.
dictionary[binder.Name.ToLower()] = value;
// You can always add a value to a dictionary,
// so this method always returns true.
return true;
}
}
class Program
{
static void Main(string[] args)
{
// Creating a dynamic dictionary.
dynamic person = new DynamicDictionary();
// Adding new dynamic properties.
// The TrySetMember method is called.
person.FirstName = "Ellen";
person.LastName = "Adams";
// Getting values of the dynamic properties.
// The TryGetMember method is called.
// Note that property names are case-insensitive.
Console.WriteLine(person.firstname + " " + person.lastname);
// Getting the value of the Count property.
// The TryGetMember is not called,
// because the property is defined in the class.
Console.WriteLine(
"Number of dynamic properties:" + person.Count);
// The following statement throws an exception at run time.
// There is no "address" property,
// so the TryGetMember method returns false and this causes a
// RuntimeBinderException.
// Console.WriteLine(person.address);
}
}
// This example has the following output:
// Ellen Adams
// Number of dynamic properties: 2
' The class derived from DynamicObject.
Public Class DynamicDictionary
Inherits DynamicObject
' The inner dictionary.
Dim dictionary As New Dictionary(Of String, Object)
' This property returns the number of elements
' in the inner dictionary.
ReadOnly Property Count As Integer
Get
Return dictionary.Count
End Get
End Property
' If you try to get a value of a property that is
' not defined in the class, this method is called.
Public Overrides Function TryGetMember(
ByVal binder As System.Dynamic.GetMemberBinder,
ByRef result As Object) As Boolean
' Converting the property name to lowercase
' so that property names become case-insensitive.
Dim name As String = binder.Name.ToLower()
' If the property name is found in a dictionary,
' set the result parameter to the property value and return true.
' Otherwise, return false.
Return dictionary.TryGetValue(name, result)
End Function
Public Overrides Function TrySetMember(
ByVal binder As System.Dynamic.SetMemberBinder,
ByVal value As Object) As Boolean
' Converting the property name to lowercase
' so that property names become case-insensitive.
dictionary(binder.Name.ToLower()) = value
' You can always add a value to a dictionary,
' so this method always returns true.
Return True
End Function
End Class
Sub Main()
' Creating a dynamic dictionary.
Dim person As Object = New DynamicDictionary()
' Adding new dynamic properties.
' The TrySetMember method is called.
person.FirstName = "Ellen"
person.LastName = "Adams"
' Getting values of the dynamic properties.
' The TryGetMember method is called.
' Note that property names are now case-insensitive,
' although they are case-sensitive in C#.
Console.WriteLine(person.firstname & " " & person.lastname)
' Getting the value of the Count property.
' The TryGetMember is not called,
' because the property is defined in the class.
Console.WriteLine("Number of dynamic properties:" & person.Count)
' The following statement throws an exception at run time.
' There is no "address" property,
' so the TryGetMember method returns false and this causes
' a MissingMemberException.
' Console.WriteLine(person.address)
End Sub
' This examples has the following output:
' Ellen Adams
' Number of dynamic properties: 2
更多範例請參見 C# 常見問題部落格上的 「用 Dynamic Object 建立包裝器 」。
備註
這個 DynamicObject 類別讓你能定義可以對動態物件執行哪些操作,以及如何執行這些操作。 例如,你可以定義當你嘗試取得或設定物件屬性、呼叫方法,或執行標準數學運算如加法和乘法時會發生什麼。
如果你想為函式庫建立更方便的協定,這堂課會很有用。 例如,如果你函式庫的使用者必須使用像 Scriptobj.SetProperty("Count", 1)這樣的語法,你可以提供使用更簡單的語法功能,例如 scriptobj.Count = 1。
你無法直接建立該 DynamicObject 類別的實例。 要實作動態行為,你可能想從類別繼承 DynamicObject 並覆蓋必要的方法。 例如,如果你只需要設定和取得屬性的操作,你可以只 TrySetMember 覆蓋 and TryGetMember 方法。
在 C# 中,要啟用由該 DynamicObject 類別衍生的類別實例的動態行為,必須使用 dynamic 關鍵字。 如需詳細資訊,請參閱 使用動態類型。
在 Visual Basic 中,晚期系結支持動態作業。 如需詳細資訊,請參閱 早期和晚期系結 (Visual Basic) 。
以下程式碼範例示範如何建立由該 DynamicObject 類別衍生的類別實例。
public class SampleDynamicObject : DynamicObject {}
//...
dynamic sampleObject = new SampleDynamicObject ();
Public Class SampleDynamicObject
Inherits DynamicObject
'...
Dim sampleObject As Object = New SampleDynamicObject()
你也可以將自己的成員加入由該 DynamicObject 類別衍生的類別中。 如果你的類別定義屬性並覆蓋該 TrySetMember 方法,動態語言執行時(DLR)會先使用語言綁定器尋找類別中屬性的靜態定義。 若不存在此性質,DLR 會呼叫該 TrySetMember 方法。
該 DynamicObject 類別實作了 DLR 介面 IDynamicMetaObjectProvider,讓你能在支援 DLR 互通模型的語言間共享該 DynamicObject 類別的實例。 例如,您可以在 C# 中建立 類別的 DynamicObject 實例,然後將它傳遞至 IronPython 函式。 欲了解更多資訊,請參閱 動態語言執行時概述。
備註
如果你有一個簡單的情境,需要一個只能在執行時新增和移除成員,但不需要定義特定操作且沒有靜態成員的物件,請使用 該 ExpandoObject 類別。
如果你有更進階的情境,需要定義動態物件如何參與互通性協定,或是需要管理 DLR 快速動態派遣快取,請自行實作介面 IDynamicMetaObjectProvider 。
建構函式
| 名稱 | Description |
|---|---|
| DynamicObject() |
使衍生型態能夠初始化該 DynamicObject 型別的新實例。 |
方法
| 名稱 | Description |
|---|---|
| Equals(Object) |
判斷指定的物件是否等於目前的物件。 (繼承來源 Object) |
| GetDynamicMemberNames() |
回傳所有動態成員名稱的枚舉。 |
| GetHashCode() |
做為預設哈希函式。 (繼承來源 Object) |
| GetMetaObject(Expression) |
提供 DynamicMetaObject 一個可以派遣到動態虛擬方法的 物件可以封裝在另一個 DynamicMetaObject 物件中,為個別動作提供自訂行為。 此方法支援語言實作者的動態語言執行環境基礎設施,並非直接從您的程式碼中使用。 |
| GetType() |
取得目前實例的 Type。 (繼承來源 Object) |
| MemberwiseClone() |
建立目前 Object的淺層複本。 (繼承來源 Object) |
| ToString() |
傳回表示目前 物件的字串。 (繼承來源 Object) |
| TryBinaryOperation(BinaryOperationBinder, Object, Object) |
提供二進位運算的實作。 從該 DynamicObject 類別衍生的類別可以覆寫此方法,以指定加法與乘法等運算的動態行為。 |
| TryConvert(ConvertBinder, Object) |
提供型別轉換操作的實作。 從該 DynamicObject 類別衍生的類別可以覆寫此方法,以指定將物件從一種型態轉換到另一種型態的動態行為。 |
| TryCreateInstance(CreateInstanceBinder, Object[], Object) |
提供初始化動態物件新實例的操作實作。 此方法不適用於 C# 或 Visual Basic。 |
| TryDeleteIndex(DeleteIndexBinder, Object[]) |
提供以索引刪除物件的操作實作。 此方法不適用於 C# 或 Visual Basic。 |
| TryDeleteMember(DeleteMemberBinder) |
提供刪除物件成員操作的實作。 此方法不適用於 C# 或 Visual Basic。 |
| TryGetIndex(GetIndexBinder, Object[], Object) |
提供透過索引取得值的操作實作。 從該 DynamicObject 類別衍生的類別可以覆寫此方法,以指定索引操作的動態行為。 |
| TryGetMember(GetMemberBinder, Object) |
提供取得成員值的操作實作。 從該 DynamicObject 類別衍生的類別可以覆寫此方法,以指定動態行為,例如取得屬性值。 |
| TryInvoke(InvokeBinder, Object[], Object) |
提供呼叫物件操作的實作。 從該 DynamicObject 類別衍生的類別可以覆寫此方法,以指定像是調用物件或代理等操作的動態行為。 |
| TryInvokeMember(InvokeMemberBinder, Object[], Object) |
提供呼叫成員操作的實作。 從該 DynamicObject 類別衍生的類別可以覆寫此方法,以指定操作的動態行為,例如呼叫方法。 |
| TrySetIndex(SetIndexBinder, Object[], Object) |
提供以索引設定值的操作實作。 從該 DynamicObject 類別衍生的類別可以覆寫此方法,以指定對透過指定索引存取物件的操作進行動態行為。 |
| TrySetMember(SetMemberBinder, Object) |
提供設定成員值的操作實作。 由該 DynamicObject 類別衍生的類別可以覆寫此方法,以指定動態行為,例如設定屬性值。 |
| TryUnaryOperation(UnaryOperationBinder, Object) |
提供一元運算的實作。 由該 DynamicObject 類別衍生的類別可以覆寫此方法,以指定如否定、遞增或遞減等操作的動態行為。 |