Condividi tramite


Classe System.Dynamic.ExpandoObject

Questo articolo fornisce osservazioni supplementari alla documentazione di riferimento per questa API.

La ExpandoObject classe consente di aggiungere ed eliminare membri delle relative istanze in fase di esecuzione, nonché di impostare e ottenere valori di questi membri. Questa classe supporta l'associazione dinamica, che consente di usare la sintassi standard, ad sampleObject.sampleMember esempio anziché una sintassi più complessa, ad esempio sampleObject.GetAttribute("sampleMember").

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

La ExpandoObject classe è un'implementazione del concetto di oggetto dinamico che consente di ottenere, impostare e richiamare membri. Se si desidera definire i tipi che dispongono della propria semantica dispatch dinamica, usare la DynamicObject classe . Se si vuole definire il modo in cui gli oggetti dinamici partecipano al protocollo di interoperabilità e gestiscono la memorizzazione nella cache della distribuzione dinamica veloce DLR, creare la propria implementazione dell'interfaccia IDynamicMetaObjectProvider .

Creare un'istanza

In C#, per abilitare l'associazione tardiva per un'istanza della ExpandoObject 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 della ExpandoObject classe .

dynamic sampleObject = new ExpandoObject();
Dim sampleObject As Object = New ExpandoObject()

Aggiungere nuovi membri

È possibile aggiungere proprietà, metodi ed eventi alle istanze della ExpandoObject classe .

Nell'esempio di codice seguente viene illustrato come aggiungere una nuova proprietà a un'istanza della ExpandoObject classe .

sampleObject.test = "Dynamic Property";
Console.WriteLine(sampleObject.test);
Console.WriteLine(sampleObject.test.GetType());
// This code example produces the following output:
// Dynamic Property
// System.String
sampleObject.Test = "Dynamic Property"
Console.WriteLine(sampleObject.test)
Console.WriteLine(sampleObject.test.GetType())
' This code example produces the following output:
' Dynamic Property
' System.String

I metodi rappresentano espressioni lambda archiviate come delegati, che possono essere richiamate quando sono necessarie. Nell'esempio di codice seguente viene illustrato come aggiungere un metodo che incrementa un valore della proprietà dinamica.

sampleObject.number = 10;
sampleObject.Increment = (Action)(() => { sampleObject.number++; });

// Before calling the Increment method.
Console.WriteLine(sampleObject.number);

sampleObject.Increment();

// After calling the Increment method.
Console.WriteLine(sampleObject.number);
// This code example produces the following output:
// 10
// 11
sampleObject.Number = 10
sampleObject.Increment = Function() sampleObject.Number + 1
' Before calling the Increment method.
Console.WriteLine(sampleObject.number)

sampleObject.Increment.Invoke()

' After calling the Increment method.
Console.WriteLine(sampleObject.number)
' This code example produces the following output:
' 10
' 11

Nell'esempio di codice seguente viene illustrato come aggiungere un evento a un'istanza della ExpandoObject classe .

class Program
{
    static void Main(string[] args)
    {
        dynamic sampleObject = new ExpandoObject();

        // Create a new event and initialize it with null.
        sampleObject.sampleEvent = null;

        // Add an event handler.
        sampleObject.sampleEvent += new EventHandler(SampleHandler);

        // Raise an event for testing purposes.
        sampleObject.sampleEvent(sampleObject, new EventArgs());
   }

    // Event handler.
    static void SampleHandler(object sender, EventArgs e)
    {
        Console.WriteLine("SampleHandler for {0} event", sender);
    }
}
// This code example produces the following output:
// SampleHandler for System.Dynamic.ExpandoObject event.
Module Module1

Sub Main()
    Dim sampleObject As Object = New ExpandoObject()

    ' Create a new event and initialize it with null.
    sampleObject.sampleEvent = Nothing

    ' Add an event handler.
    Dim handler As EventHandler = AddressOf SampleHandler
    sampleObject.sampleEvent =
        [Delegate].Combine(sampleObject.sampleEvent, handler)

    ' Raise an event for testing purposes.
    sampleObject.sampleEvent.Invoke(sampleObject, New EventArgs())

End Sub

' Event handler.
Sub SampleHandler(ByVal sender As Object, ByVal e As EventArgs)
    Console.WriteLine("SampleHandler for {0} event", sender)
End Sub

' This code example produces the following output:
' SampleHandler for System.Dynamic.ExpandoObject event.

End Module

Passare come parametro

È possibile passare istanze della ExpandoObject classe come parametri. Si noti che queste istanze vengono considerate come oggetti dinamici in C# e oggetti con associazione tardiva in Visual Basic. Ciò significa che non si dispone di IntelliSense per i membri dell'oggetto e non si ricevono errori del compilatore quando si chiamano membri inesistenti. Se si chiama un membro che non esiste, si verifica un'eccezione.

Nell'esempio di codice seguente viene illustrato come creare e usare un metodo per stampare i nomi e i valori delle proprietà.

class Program
{
    static void Main(string[] args)
    {
        dynamic employee, manager;

        employee = new ExpandoObject();
        employee.Name = "John Smith";
        employee.Age = 33;

        manager = new ExpandoObject();
        manager.Name = "Allison Brown";
        manager.Age = 42;
        manager.TeamSize = 10;

        WritePerson(manager);
        WritePerson(employee);
    }
    private static void WritePerson(dynamic person)
    {
        Console.WriteLine("{0} is {1} years old.",
                          person.Name, person.Age);
        // The following statement causes an exception
        // if you pass the employee object.
        // Console.WriteLine("Manages {0} people", person.TeamSize);
    }
}
// This code example produces the following output:
// John Smith is 33 years old.
// Allison Brown is 42 years old.
Sub Main()
    Dim employee, manager As Object

    employee = New ExpandoObject()
    employee.Name = "John Smith"
    employee.Age = 33

    manager = New ExpandoObject()
    manager.Name = "Allison Brown"
    manager.Age = 42
    manager.TeamSize = 10

    WritePerson(manager)
    WritePerson(employee)
End Sub

Private Sub WritePerson(ByVal person As Object)

    Console.WriteLine("{0} is {1} years old.",
                      person.Name, person.Age)
    ' The following statement causes an exception
    ' if you pass the employee object.
    ' Console.WriteLine("Manages {0} people", person.TeamSize)

End Sub

Enumerare ed eliminare membri

La classe ExpandoObject implementa l'interfaccia IDictionary<String, Object>. Ciò consente l'enumerazione dei membri aggiunti all'istanza della ExpandoObject classe in fase di esecuzione. Ciò può essere utile se non si conosce in fase di compilazione quali membri potrebbero avere un'istanza di .

Nell'esempio di codice seguente viene illustrato come eseguire il cast di un'istanza della ExpandoObject classe all'interfaccia IDictionary<TKey,TValue> ed enumerare i membri dell'istanza.

dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;

foreach (var property in (IDictionary<String, Object>)employee)
{
    Console.WriteLine(property.Key + ": " + property.Value);
}
// This code example produces the following output:
// Name: John Smith
// Age: 33
Dim employee As Object = New ExpandoObject()
employee.Name = "John Smith"
employee.Age = 33
For Each member In CType(employee, IDictionary(Of String, Object))
    Console.WriteLine(member.Key & ": " & member.Value)
Next
' This code example produces the following output:
' Name: John Smith
' Age: 33

Nei linguaggi che non dispongono di sintassi per l'eliminazione di membri ,ad esempio C# e Visual Basic, è possibile eliminare un membro eseguendo in modo implicito il cast di un'istanza di nell'interfaccia ExpandoObjectIDictionary<String, Object> e quindi eliminando il membro come coppia chiave/valore. come illustrato nell'esempio seguente.

dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
((IDictionary<String, Object>)employee).Remove("Name");
Dim employee As Object = New ExpandoObject()
employee.Name = "John Smith"
CType(employee, IDictionary(Of String, Object)).Remove("Name")

Ricevere notifiche di modifiche alle proprietà

La ExpandoObject classe implementa l'interfaccia INotifyPropertyChanged e può generare un PropertyChanged evento quando un membro viene aggiunto, eliminato o modificato. Ciò consente l'integrazione ExpandoObject di classi con il data binding di Windows Presentation Foundation (WPF) e altri ambienti che richiedono notifiche sulle modifiche nel contenuto dell'oggetto.

Nell'esempio di codice seguente viene illustrato come creare un gestore eventi per l'evento PropertyChanged .

// Add "using System.ComponentModel;" line
// to the beginning of the file.
class Program
{
    static void Test()
    {
        dynamic employee = new ExpandoObject();
        ((INotifyPropertyChanged)employee).PropertyChanged +=
            new PropertyChangedEventHandler(HandlePropertyChanges);
        employee.Name = "John Smith";
    }

    private static void HandlePropertyChanges(
        object sender, PropertyChangedEventArgs e)
    {
        Console.WriteLine("{0} has changed.", e.PropertyName);
    }
}
' Add "Imports System.ComponentModel" line 
' to the beginning of the file.
Sub Main()
    Dim employee As Object = New ExpandoObject
    AddHandler CType(
        employee, INotifyPropertyChanged).PropertyChanged,
        AddressOf HandlePropertyChanges
    employee.Name = "John Smith"
End Sub

Private Sub HandlePropertyChanges(
       ByVal sender As Object, ByVal e As PropertyChangedEventArgs)
    Console.WriteLine("{0} has changed.", e.PropertyName)
End Sub