Delen via


Klasse System.Dynamic.ExpandoObject

In dit artikel vindt u aanvullende opmerkingen in de referentiedocumentatie voor deze API.

Met de ExpandoObject klasse kunt u tijdens runtime leden van de exemplaren toevoegen en verwijderen en ook waarden van deze leden instellen en ophalen. Deze klasse ondersteunt dynamische binding, waarmee u standaardsyntaxis kunt gebruiken, zoals sampleObject.sampleMember in plaats van complexere syntaxis, zoals sampleObject.GetAttribute("sampleMember").

De ExpandoObject klasse implementeert de standaard DLR-interface IDynamicMetaObjectProvider(Dynamic Language Runtime), waarmee u exemplaren van de ExpandoObject klasse kunt delen tussen talen die ondersteuning bieden voor het DLR-interoperabiliteitsmodel. U kunt bijvoorbeeld een exemplaar van de ExpandoObject klasse in C# maken en deze vervolgens doorgeven aan een IronPython-functie. Zie Dynamic Language Runtime Overview and Introducing the ExpandoObject (Engelstalig) voor meer informatie.

De ExpandoObject klasse is een implementatie van het dynamische objectconcept waarmee leden kunnen worden opgehaald, ingesteld en aangeroepen. Als u typen wilt definiëren die hun eigen dynamische verzendsemantiek hebben, gebruikt u de DynamicObject klasse. Als u wilt definiëren hoe dynamische objecten deelnemen aan het interoperabiliteitsprotocol en DLR snelle dynamische verzendingcaching beheren, maakt u uw eigen implementatie van de IDynamicMetaObjectProvider interface.

Een instantie maken

Als u in C# late binding wilt inschakelen voor een exemplaar van de ExpandoObject klasse, moet u het dynamic trefwoord gebruiken. Zie Dynamisch type gebruiken voor meer informatie.

In Visual Basic worden dynamische bewerkingen ondersteund door late binding. Zie Early and Late Binding (Visual Basic) voor meer informatie.

In het volgende codevoorbeeld ziet u hoe u een exemplaar van de ExpandoObject klasse maakt.

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

Nieuwe leden toevoegen

U kunt eigenschappen, methoden en gebeurtenissen toevoegen aan exemplaren van de ExpandoObject klasse.

In het volgende codevoorbeeld ziet u hoe u een nieuwe eigenschap toevoegt aan een exemplaar van de ExpandoObject klasse.

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

De methoden vertegenwoordigen lambda-expressies die zijn opgeslagen als gemachtigden, die kunnen worden aangeroepen wanneer ze nodig zijn. In het volgende codevoorbeeld ziet u hoe u een methode toevoegt waarmee een waarde van de dynamische eigenschap wordt verhoogd.

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

In het volgende codevoorbeeld ziet u hoe u een gebeurtenis toevoegt aan een exemplaar van de ExpandoObject klasse.

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

Doorgeven als een parameter

U kunt exemplaren van de ExpandoObject klasse doorgeven als parameters. Houd er rekening mee dat deze exemplaren worden behandeld als dynamische objecten in C# en late gebonden objecten in Visual Basic. Dit betekent dat u geen IntelliSense voor objectleden hebt en dat u geen compilerfouten ontvangt wanneer u niet-bestaande leden aanroept. Als u een lid aanroept dat niet bestaat, treedt er een uitzondering op.

In het volgende codevoorbeeld ziet u hoe u een methode kunt maken en gebruiken om de namen en waarden van eigenschappen af te drukken.

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

Leden opsommen en verwijderen

Met de klasse ExpandoObject wordt de IDictionary<String, Object>-interface geïmplementeerd. Hierdoor kunnen leden die tijdens runtime aan het exemplaar van de ExpandoObject klasse zijn toegevoegd, worden opgesomd. Dit kan handig zijn als u tijdens het compileren niet weet welke leden een exemplaar kan hebben.

In het volgende codevoorbeeld ziet u hoe u een exemplaar van de ExpandoObject klasse naar de IDictionary<TKey,TValue> interface kunt casten en de leden van het exemplaar kunt inventariseren.

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 talen die geen syntaxis hebben voor het verwijderen van leden (zoals C# en Visual Basic), kunt u een lid verwijderen door impliciet een exemplaar van de ExpandoObjectIDictionary<String, Object> interface te casten en vervolgens het lid als sleutel/waardepaar te verwijderen. Dit wordt weergegeven in het volgende voorbeeld.

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

Meldingen ontvangen over wijzigingen in eigenschappen

De ExpandoObject klasse implementeert de INotifyPropertyChanged interface en kan een PropertyChanged gebeurtenis genereren wanneer een lid wordt toegevoegd, verwijderd of gewijzigd. Hierdoor kan ExpandoObject klasseintegratie met WPF-gegevensbinding (Windows Presentation Foundation) en andere omgevingen worden gebruikt die een melding over wijzigingen in de objectinhoud vereisen.

In het volgende codevoorbeeld ziet u hoe u een gebeurtenis-handler voor de PropertyChanged gebeurtenis maakt.

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