DynamicObject 類別

定義

提供基底類別,以便指定在執行階段時的動態行為。 這個類別必須是繼承類別,您無法直接將其執行個體化。

public ref class DynamicObject : System::Dynamic::IDynamicMetaObjectProvider
public class DynamicObject : System.Dynamic.IDynamicMetaObjectProvider
[System.Serializable]
public class DynamicObject : System.Dynamic.IDynamicMetaObjectProvider
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(Of String, Object) (的物件 Dictionary<string, object> ,Visual Basic) 中用來儲存機碼/值組,並覆寫 TrySetMemberTryGetMember 方法來支援新的語法。 它也提供 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# 常見問題部落格上的 使用 DynamicObject 建立包裝 函式。

備註

類別 DynamicObject 可讓您定義哪些作業可以在動態物件上執行,以及如何執行這些作業。 例如,您可以定義當您嘗試取得或設定物件屬性、呼叫方法,或執行標準數學運算,例如加法和乘法時會發生什麼事。

如果您想要為程式庫建立更方便的通訊協定,這個類別會很有用。 例如,如果您的程式庫使用者必須使用類似 的 Scriptobj.SetProperty("Count", 1) 語法,您可以提供使用更簡單語法的能力,例如 scriptobj.Count = 1

您無法直接建立 類別的 DynamicObject 實例。 若要實作動態行為,您可能想要繼承自 DynamicObject 類別,並覆寫必要的方法。 例如,如果您只需要設定和取得屬性的作業,您可以只 TrySetMember 覆寫 和 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

建構函式

DynamicObject()

讓衍生型別得以初始化 DynamicObject 型別的新執行個體。

方法

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 類別的類別可以覆寫這個方法,以指定負號、遞增或遞減這類運算的動態行為。

適用於