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