DynamicObject Classe

Definizione

Fornisce una classe base per specificare il comportamento dinamico in fase di esecuzione. Questa classe deve essere ereditata; non è possibile crearne direttamente un'istanza.

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
Ereditarietà
DynamicObject
Derivato
Attributi
Implementazioni

Esempio

Si supponga di voler fornire una sintassi alternativa per accedere ai valori in un dizionario, in modo che invece di scrivere sampleDictionary["Text"] = "Sample text" (sampleDictionary("Text") = "Sample text" in Visual Basic), è possibile scrivere sampleDictionary.Text = "Sample text". Si vuole anche che questa sintassi sia senza distinzione tra maiuscole e minuscole, in modo che sampleDictionary.Text sia equivalente a sampleDictionary.text.

Nell'esempio DynamicObject di codice seguente viene illustrata la DynamicDictionary classe, derivata dalla classe . La DynamicDictionary classe contiene un oggetto del Dictionary<string, object> tipo (Dictionary(Of String, Object) in Visual Basic) per archiviare le coppie chiave-valore e esegue l'override dei TrySetMember metodi e TryGetMember per supportare la nuova sintassi. Fornisce inoltre una Count proprietà, che mostra il numero di proprietà dinamiche contenute nel dizionario.

// 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

Per altri esempi, vedere Creazione di wrapper con DynamicObject nel blog domande frequenti su C#.

Commenti

La DynamicObject classe consente di definire quali operazioni possono essere eseguite sugli oggetti dinamici e su come eseguire tali operazioni. Ad esempio, è possibile definire ciò che accade quando si tenta di ottenere o impostare una proprietà dell'oggetto, chiamare un metodo o eseguire operazioni matematiche standard, ad esempio l'aggiunta e la moltiplicazione.

Questa classe può essere utile se si vuole creare un protocollo più pratico per una libreria. Ad esempio, se gli utenti della libreria devono usare la sintassi come Scriptobj.SetProperty("Count", 1), è possibile fornire la possibilità di usare una sintassi molto più semplice, ad scriptobj.Count = 1esempio .

Non è possibile creare direttamente un'istanza della DynamicObject classe. Per implementare il comportamento dinamico, è possibile ereditare dalla classe e eseguire l'override DynamicObject dei metodi necessari. Ad esempio, se sono necessarie solo operazioni per l'impostazione e il recupero delle proprietà, è possibile eseguire l'override solo dei TrySetMember metodi e TryGetMember .

In C#, per abilitare il comportamento dinamico per le istanze di classi derivate dalla DynamicObject classe, è necessario usare la dynamic parola chiave. Per altre informazioni, vedere Uso del tipo dynamic.

In Visual Basic le operazioni dinamiche sono supportate dall'associazione tardiva. Per altre informazioni, vedere Associazione anticipata e tardiva (Visual Basic).

Nell'esempio di codice seguente viene illustrato come creare un'istanza DynamicObject di una classe derivata dalla classe .

public class SampleDynamicObject : DynamicObject {}  
//...  
dynamic sampleObject = new SampleDynamicObject ();  
Public Class SampleDynamicObject   
    Inherits DynamicObject  
'...  
Dim sampleObject As Object = New SampleDynamicObject()  

È anche possibile aggiungere membri personalizzati alle classi derivate dalla DynamicObject classe. Se la classe definisce le proprietà ed esegue anche l'override del metodo, il runtime di linguaggio dinamico usa prima il TrySetMember binding del linguaggio per cercare una definizione statica di una proprietà nella classe. Se non esiste alcuna proprietà di questo tipo, la DLR chiama il TrySetMember metodo .

La DynamicObject classe implementa l'interfaccia IDynamicMetaObjectProviderDLR , che consente di condividere istanze della classe tra lingue che supportano il modello di DynamicObject interoperabilità DLR. Ad esempio, è possibile creare un'istanza della DynamicObject classe in C# e quindi passarla a una funzione IronPython. Per altre informazioni, vedere Panoramica di Dynamic Language Runtime.

Nota

Se si dispone di uno scenario semplice in cui è necessario un oggetto che può aggiungere e rimuovere solo membri in fase di esecuzione, ma che non deve definire operazioni specifiche e non dispone di membri statici, usare la ExpandoObject classe .

Se si dispone di uno scenario più avanzato in cui è necessario definire il modo in cui gli oggetti dinamici partecipano al protocollo di interoperabilità oppure è necessario gestire la memorizzazione nella cache di distribuzione dinamica rapida DLR, creare la propria implementazione dell'interfaccia IDynamicMetaObjectProvider .

Costruttori

DynamicObject()

Consente ai tipi derivati di creare una nuova istanza del tipo DynamicObject.

Metodi

Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.

(Ereditato da Object)
GetDynamicMemberNames()

Restituisce l'enumerazione di tutti i nomi di membro dinamici.

GetHashCode()

Funge da funzione hash predefinita.

(Ereditato da Object)
GetMetaObject(Expression)

Fornisce un oggetto DynamicMetaObject che invia ai metodi virtuali dinamici. L'oggetto può essere incapsulato all'interno di un altro oggetto DynamicMetaObject per fornire il comportamento personalizzato per singole azioni. Questo metodo supporta l'infrastruttura DLR (Dynamic Language Runtime) per gli implementatori del linguaggio e non è destinato all'utilizzo direttamente dal codice.

GetType()

Ottiene l'oggetto Type dell'istanza corrente.

(Ereditato da Object)
MemberwiseClone()

Crea una copia superficiale dell'oggetto Object corrente.

(Ereditato da Object)
ToString()

Restituisce una stringa che rappresenta l'oggetto corrente.

(Ereditato da Object)
TryBinaryOperation(BinaryOperationBinder, Object, Object)

Fornisce l'implementazione per le operazioni binarie. Le classi derivate dalla classe DynamicObject possono eseguire l'override di questo metodo per specificare il comportamento dinamico per operazioni quali l'aggiunta e la moltiplicazione.

TryConvert(ConvertBinder, Object)

Fornisce l'implementazione per le operazioni di conversione dei tipi. Le classi derivate dalla classe DynamicObject possono eseguire l'override di questo metodo per specificare il comportamento dinamico per operazioni che eseguono la conversione di un oggetto da un tipo a un altro.

TryCreateInstance(CreateInstanceBinder, Object[], Object)

Fornisce l'implementazione per le operazioni che creano una nuova istanza di un oggetto dinamico. Questo metodo non può essere utilizzato in C# o in Visual Basic.

TryDeleteIndex(DeleteIndexBinder, Object[])

Fornisce l'implementazione per operazioni che eliminano un oggetto in base all'indice. Questo metodo non può essere utilizzato in C# o in Visual Basic.

TryDeleteMember(DeleteMemberBinder)

Fornisce l'implementazione per operazioni che eliminano un membro di un oggetto. Questo metodo non può essere utilizzato in C# o in Visual Basic.

TryGetIndex(GetIndexBinder, Object[], Object)

Fornisce l'implementazione per operazioni che ottengono un valore in base all'indice. Le classi derivate dalla classe DynamicObject possono eseguire l'override di questo metodo per specificare il comportamento dinamico per operazioni di indicizzazione.

TryGetMember(GetMemberBinder, Object)

Fornisce l'implementazione per operazioni che ottengono valori dei membri. Le classi derivate dalla classe DynamicObject possono eseguire l'override di questo metodo per specificare il comportamento dinamico per operazioni quale l'acquisizione di un valore per una proprietà.

TryInvoke(InvokeBinder, Object[], Object)

Fornisce l'implementazione per operazioni che richiamano un oggetto. Le classi derivate dalla classe DynamicObject possono eseguire l'override di questo metodo per specificare il comportamento dinamico per operazioni quale il richiamo di un oggetto o un delegato.

TryInvokeMember(InvokeMemberBinder, Object[], Object)

Fornisce l'implementazione per operazioni che richiamano un membro. Le classi derivate dalla classe DynamicObject possono eseguire l'override di questo metodo per specificare il comportamento dinamico per operazioni quale la chiamata a un metodo.

TrySetIndex(SetIndexBinder, Object[], Object)

Fornisce l'implementazione per operazioni che impostano un valore in base all'indice. Le classi derivate dalla classe DynamicObject possono eseguire l'override di questo metodo per specificare il comportamento dinamico per operazioni che accedono a oggetti in base a un indice specificato.

TrySetMember(SetMemberBinder, Object)

Fornisce l'implementazione per operazioni che impostano valori dei membri. Le classi derivate dalla classe DynamicObject possono eseguire l'override di questo metodo per specificare il comportamento dinamico per operazioni quale l'impostazione di un valore per una proprietà.

TryUnaryOperation(UnaryOperationBinder, Object)

Fornisce l'implementazione per le operazioni unarie. Le classi derivate dalla classe DynamicObject possono eseguire l'override di questo metodo per specificare il comportamento dinamico per operazioni quale negazione, incremento o decremento.

Si applica a