System.Dynamic.ExpandoObject-Klasse

Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.

Mit der ExpandoObject Klasse können Sie zur Laufzeit Member seiner Instanzen hinzufügen und löschen sowie Werte dieser Member festlegen und abrufen. Diese Klasse unterstützt dynamische Bindung, mit der Sie standardsyntax wie sampleObject.sampleMember z. B. eine komplexere Syntax wie sampleObject.GetAttribute("sampleMember")z. B. verwenden können.

Die ExpandoObject Klasse implementiert die standardschnittstelle IDynamicMetaObjectProviderDynamic Language Runtime (DLR), mit der Sie Instanzen der ExpandoObject Klasse zwischen Sprachen freigeben können, die das DLR-Interoperabilitätsmodell unterstützen. Sie können beispielsweise eine Instanz der ExpandoObject Klasse in C# erstellen und dann an eine IronPython-Funktion übergeben. Weitere Informationen finden Sie unter Dynamic Language Runtime Overview and Introducing the ExpandoObject.

Die ExpandoObject Klasse ist eine Implementierung des dynamischen Objektkonzepts, das das Abrufen, Festlegen und Aufrufen von Elementen ermöglicht. Wenn Sie Typen definieren möchten, die über eine eigene dynamische Dispatchsemantik verfügen, verwenden Sie die DynamicObject Klasse. Wenn Sie definieren möchten, wie dynamische Objekte am Interoperabilitätsprotokoll teilnehmen und dlr schnelle dynamische Versandzwischenspeicherung verwalten möchten, erstellen Sie ihre eigene Implementierung der IDynamicMetaObjectProvider Schnittstelle.

Erstellen einer Instanz

Wenn Sie in C# eine späte Bindung für eine Instanz der ExpandoObject Klasse aktivieren möchten, müssen Sie die dynamic Schlüsselwort (keyword) verwenden. Weitere Informationen finden Sie unter Verwenden von dynamischen Typen.

In Visual Basic werden dynamische Vorgänge durch späte Bindung unterstützt. Weitere Informationen finden Sie unter Early and Late Binding (Visual Basic).

Im folgenden Codebeispiel wird veranschaulicht, wie eine Instanz der ExpandoObject Klasse erstellt wird.

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

Neue Mitglieder hinzufügen

Sie können Instanzen der ExpandoObject Klasse Eigenschaften, Methoden und Ereignisse hinzufügen.

Im folgenden Codebeispiel wird veranschaulicht, wie sie einer Instanz der ExpandoObject Klasse eine neue Eigenschaft hinzufügen.

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

Die Methoden stellen Lambda-Ausdrücke dar, die als Stellvertretungen gespeichert werden, die bei Bedarf aufgerufen werden können. Das folgende Codebeispiel veranschaulicht das Hinzufügen einer Methode, die einen Wert der dynamischen Eigenschaft erhöht.

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

Im folgenden Codebeispiel wird das Hinzufügen eines Ereignisses zu einer Instanz der ExpandoObject Klasse veranschaulicht.

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

Übergeben als Parameter

Sie können Instanzen der ExpandoObject Klasse als Parameter übergeben. Beachten Sie, dass diese Instanzen in C# und spät gebundenen Objekten in Visual Basic als dynamische Objekte behandelt werden. Dies bedeutet, dass Sie nicht über IntelliSense für Objektmber verfügen und keine Compilerfehler erhalten, wenn Sie nicht vorhandene Member aufrufen. Wenn Sie ein Element aufrufen, das nicht vorhanden ist, tritt eine Ausnahme auf.

Im folgenden Codebeispiel wird veranschaulicht, wie Sie eine Methode erstellen und verwenden können, um die Namen und Werte von Eigenschaften zu drucken.

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

Aufzählen und Löschen von Mitgliedern

Die ExpandoObject-Klasse implementiert die IDictionary<String, Object>-Schnittstelle. Dadurch wird die Enumeration von Membern ermöglicht, die der Instanz der ExpandoObject Klasse zur Laufzeit hinzugefügt wurden. Dies kann hilfreich sein, wenn Sie zur Kompilierungszeit nicht wissen, welche Member eine Instanz haben könnte.

Das folgende Codebeispiel zeigt, wie Sie eine Instanz der ExpandoObject Klasse in die IDictionary<TKey,TValue> Schnittstelle umwandeln und die Member der Instanz aufzählen können.

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

In Sprachen ohne Syntax zum Löschen von Elementen (z. B. C# und Visual Basic) können Sie ein Element löschen, indem Sie eine Instanz der ExpandoObjectIDictionary<String, Object> Schnittstelle implizit umwandeln und dann das Element als Schlüssel-Wert-Paar löschen. Dies wird im folgenden Beispiel gezeigt.

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")

Empfangen von Benachrichtigungen über Eigenschaftsänderungen

Die ExpandoObject Klasse implementiert die INotifyPropertyChanged Schnittstelle und kann ein PropertyChanged Ereignis auslösen, wenn ein Element hinzugefügt, gelöscht oder geändert wird. Dies ermöglicht ExpandoObject die Klassenintegration in die WPF-Datenbindung (Windows Presentation Foundation) und andere Umgebungen, die Benachrichtigungen zu Änderungen im Objektinhalt erfordern.

Im folgenden Codebeispiel wird das Erstellen eines Ereignishandlers für das PropertyChanged Ereignis veranschaulicht.

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