System.Dynamic.ExpandoObject, klasa

Ten artykuł zawiera dodatkowe uwagi dotyczące dokumentacji referencyjnej dla tego interfejsu API.

Klasa ExpandoObject umożliwia dodawanie i usuwanie elementów członkowskich jej wystąpień w czasie wykonywania, a także ustawianie i pobieranie wartości tych elementów członkowskich. Ta klasa obsługuje powiązanie dynamiczne, co umożliwia używanie standardowej składni, takiej jak sampleObject.sampleMember zamiast bardziej złożonej składni, takiej jak sampleObject.GetAttribute("sampleMember").

Klasa ExpandoObject implementuje standardowy interfejs IDynamicMetaObjectProviderDynamic Language Runtime (DLR), który umożliwia udostępnianie wystąpień ExpandoObject klasy między językami obsługującymi model współdziałania DLR. Możesz na przykład utworzyć wystąpienie ExpandoObject klasy w języku C#, a następnie przekazać je do funkcji IronPython. Aby uzyskać więcej informacji, zobacz Dynamic Language Runtime Overview (Omówienie środowiska uruchomieniowego języka dynamicznego) i Introducing the ExpandoObject (Omówienie środowiska uruchomieniowego języka dynamicznego) i Introducing the ExpandoObject (Wprowadzenie do obiektu ExpandoObject).

Klasa ExpandoObject jest implementacją koncepcji obiektu dynamicznego, która umożliwia uzyskiwanie, ustawianie i wywoływanie elementów członkowskich. Jeśli chcesz zdefiniować typy, które mają własną semantykę wysyłania dynamicznego, użyj DynamicObject klasy . Jeśli chcesz zdefiniować, w jaki sposób obiekty dynamiczne uczestniczą w protokole współdziałania i zarządzaj szybkim buforowaniem dynamicznego wysyłania DLR, utwórz własną implementację interfejsu IDynamicMetaObjectProvider .

Tworzenie wystąpienia

Aby włączyć późne powiązanie dla wystąpienia ExpandoObject klasy w języku C#, należy użyć słowa kluczowego dynamic . Aby uzyskać więcej informacji, zobacz Using Type dynamic (Używanie dynamicznego typu).

W języku Visual Basic operacje dynamiczne są obsługiwane przez opóźnione powiązanie. Aby uzyskać więcej informacji, zobacz Wczesne i późne powiązanie (Visual Basic).

W poniższym przykładzie kodu pokazano, jak utworzyć wystąpienie ExpandoObject klasy.

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

Dodawanie nowych członków

Do wystąpień ExpandoObject klasy można dodawać właściwości, metody i zdarzenia.

W poniższym przykładzie kodu pokazano, jak dodać nową właściwość do wystąpienia ExpandoObject klasy.

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

Metody reprezentują wyrażenia lambda przechowywane jako delegaty, które mogą być wywoływane, gdy są potrzebne. W poniższym przykładzie kodu pokazano, jak dodać metodę, która zwiększa wartość właściwości dynamicznej.

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

W poniższym przykładzie kodu pokazano, jak dodać zdarzenie do wystąpienia ExpandoObject klasy.

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

Przekazywanie jako parametru

Wystąpienia klasy można przekazać ExpandoObject jako parametry. Należy pamiętać, że te wystąpienia są traktowane jako obiekty dynamiczne w języku C# i obiekty związane z późnym opóźnieniem w Visual Basic. Oznacza to, że nie masz funkcji IntelliSense dla elementów członkowskich obiektów i nie otrzymujesz błędów kompilatora podczas wywoływania nieistniejących elementów członkowskich. Jeśli wywołasz członka, który nie istnieje, wystąpi wyjątek.

W poniższym przykładzie kodu pokazano, jak utworzyć metodę i użyć jej do drukowania nazw i wartości właściwości.

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

Wyliczanie i usuwanie elementów członkowskich

Klasa ExpandoObject implementuje interfejs IDictionary<String, Object>. Umożliwia to wyliczanie elementów członkowskich dodanych do wystąpienia ExpandoObject klasy w czasie wykonywania. Może to być przydatne, jeśli nie wiesz w czasie kompilacji, jakie elementy członkowskie mogą mieć wystąpienie.

Poniższy przykład kodu pokazuje, jak można rzutować wystąpienie ExpandoObject klasy do interfejsu IDictionary<TKey,TValue> i wyliczać składowe wystąpienia.

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

W językach, które nie mają składni usuwania elementów członkowskich (takich jak C# i Visual Basic), można usunąć element członkowski niejawnie rzutując wystąpienie ExpandoObject elementu do interfejsu IDictionary<String, Object> , a następnie usuwając element członkowski jako parę klucz/wartość. Jest to pokazane w następującym przykładzie.

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

Otrzymywanie powiadomień o zmianach właściwości

Klasa ExpandoObject implementuje INotifyPropertyChanged interfejs i może zgłosić PropertyChanged zdarzenie po dodaniu, usunięciu lub zmodyfikowaniu elementu członkowskiego. ExpandoObject Umożliwia to integrację klas z powiązaniem danych programu Windows Presentation Foundation (WPF) i innymi środowiskami, które wymagają powiadomienia o zmianach w zawartości obiektu.

W poniższym przykładzie kodu pokazano, jak utworzyć program obsługi zdarzeń dla PropertyChanged zdarzenia.

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