Jakie są różnice między System.Dynamic.ExpandoObject
, System.Dynamic.DynamicObject
i dynamic
?
W jakich sytuacjach używasz tych typów?
Jakie są różnice między System.Dynamic.ExpandoObject
, System.Dynamic.DynamicObject
i dynamic
?
W jakich sytuacjach używasz tych typów?
Słowo dynamic
kluczowe służy do deklarowania zmiennych, które powinny być wiązane późno.
Jeśli chcesz użyć późnego wiązania, dla dowolnego typu rzeczywistego lub wyobrażonego, użyj dynamic
słowa kluczowego, a kompilator zajmie się resztą.
Gdy używasz dynamic
słowa kluczowego do interakcji z normalnym wystąpieniem, DLR wykonuje wywołania z późnym wiązaniem do normalnych metod wystąpienia.
IDynamicMetaObjectProvider
Interfejs pozwala klasa przejąć kontrolę nad jego późno związana zachowania.
Kiedy używasz dynamic
słowa kluczowego do interakcji z IDynamicMetaObjectProvider
implementacją, DLR wywołuje IDynamicMetaObjectProvider
metody, a sam obiekt decyduje, co zrobić.
ExpandoObject
I DynamicObject
zajęcia są implementacje IDynamicMetaObjectProvider
.
ExpandoObject
to prosta klasa, która umożliwia dodawanie członków do instancji i używanie ich jako dynamic
sojuszników.
DynamicObject
to bardziej zaawansowana implementacja, którą można odziedziczyć w celu łatwego zapewnienia dostosowanego zachowania.
Postaram się udzielić jaśniejszej odpowiedzi na to pytanie, aby jasno wyjaśnić, jakie są różnice między dynamiką
ExpandoObject
aDynamicObject
.Bardzo szybko
dynamic
to słowo kluczowe. To nie jest typ jako taki. Jest to słowo kluczowe, które mówi kompilatorowi, aby ignorował sprawdzanie typu statycznego w czasie projektowania i zamiast tego używał późnego wiązania w czasie wykonywania. Więc nie będziemy spędzać dużo czasudynamic
w dalszej części tej odpowiedzi.ExpandoObject
iDynamicObject
rzeczywiście są typami. NA POWIERZCHNI wyglądają bardzo podobnie do siebie. Obie klasy implementująIDynamicMetaObjectProvider
. Jednak kop głębiej, a przekonasz się, że wcale NIE są podobne.DynamicObject jest częściową implementacją, która
IDynamicMetaObjectProvider
ma być wyłącznie punktem wyjścia dla programistów do implementacji własnych niestandardowych typów obsługujących dynamiczne wysyłanie z niestandardowym podstawowym zachowaniem pamięci i pobierania, aby dynamiczna wysyłka działała.Krótko mówiąc, użyj DynamicObject, gdy chcesz stworzyć własne typy, które mogą być używane z DLR i pracować z dowolnymi NIESTANDARDOWYMI zachowaniami, jakie chcesz.
Przykład: Wyobraź sobie, że chciałbyś mieć typ dynamiczny, który zwraca niestandardową wartość domyślną za każdym razem, gdy podejmowana jest próba pobrania na elemencie, który NIE istnieje (tj. Nie został dodany w czasie wykonywania). Domyślnie powie: „Przepraszam, w tym słoiku nie ma ciasteczek!”. Jeśli chcesz dynamicznego obiektu, który zachowuje się w ten sposób, musisz kontrolować, co się dzieje, gdy pole nie zostanie znalezione. ExpandoObject nie pozwoli ci tego zrobić. Musisz więc utworzyć własny typ z unikalnym dynamicznym zachowaniem rozdzielczości elementu członkowskiego (wysyłką) i użyć go zamiast gotowego
ExpandoObject
.Możesz utworzyć typ w następujący sposób: (Uwaga, poniższy kod jest tylko ilustracją i może nie działać. Aby dowiedzieć się, jak prawidłowo używać DynamicObject, istnieje wiele artykułów i samouczków w innych miejscach).
Teraz moglibyśmy użyć tej wyimaginowanej klasy, którą właśnie utworzyliśmy jako typ dynamiczny, który ma bardzo niestandardowe zachowanie, jeśli pole nie istnieje.
ExpandoObject
jest PEŁNĄ implementacjąIDynamicMetaObjectProvider
, w której zespół .NET Framework podjął wszystkie te decyzje za Ciebie. Jest to przydatne, jeśli nie potrzebujesz żadnego niestandardowego zachowania i uważasz, że ExpandoObject działa dla Ciebie wystarczająco dobrze (w 90% przypadkówExpandoObject
jest wystarczająco dobry). Na przykład zobacz poniższe, a dla ExpandoObject projektanci zdecydowali się zgłosić wyjątek, jeśli dynamiczny element członkowski nie istnieje.Podsumowując,
ExpandoObject
jest to po prostu jeden z wstępnie wybranych sposobów rozszerzenia DynamicObject o pewne dynamiczne zachowania wysyłania, które prawdopodobnie będą dla Ciebie odpowiednie , ale mogą nie zależeć od Twoich konkretnych potrzeb.Natomiast
DyanmicObject
jest to pomocnik BaseType, który sprawia, że implementowanie własnych typów z unikalnymi dynamicznymi zachowaniami jest proste i łatwe.Przydatny samouczek, na którym opiera się większość powyższego przykładowego źródła.
źródło
DynamicObject
: podczas zastępowaniaTryGetMember
, jeśli zwrócisz false,RuntimeBinderException
zostanie wyrzucony podczas próby dostępu do nieistniejącej właściwości. Aby fragment faktycznie działał, należy wrócićtrue
.Zgodnie ze specyfikacją języka C #
dynamic
jest to deklaracja typu. Oznaczadynamic x
to, że zmiennax
ma typdynamic
.DynamicObject
jest typem, który ułatwia implementację,IDynamicMetaObjectProvider
a tym samym zastępuje specyficzne zachowanie wiązania dla typu.ExpandoObject
jest typem, który działa jak worek mienia. Oznacza to, że możesz dodawać właściwości, metody i tak dalej do dynamicznych instancji tego typu w czasie wykonywania.źródło
dynamic
nie jest rzeczywistym typem ... jest to tylko wskazówka, aby powiedzieć kompilatorowi, aby używał późnego wiązania dla tej zmiennej.dynamic
zmienne są faktycznie deklarowane jakobject
w MSILPowyższy przykład
DynamicObject
nie wyjaśnia wyraźnie różnicy, ponieważ w zasadzie implementuje funkcjonalność, która jest już dostarczona przezExpandoObject
.W dwóch wymienionych poniżej linkach jest bardzo jasne, że za pomocą
DynamicObject
można zachować / zmienić rzeczywisty typ (XElement
w przykładzie użytym w poniższych linkach) i lepszą kontrolę właściwości i metod.https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-the-expandoobject/
https://blogs.msdn.microsoft.com/csharpfaq/2009/10/19/dynamic-in-c-4-0-creating-wrappers-with-dynamicobject/
źródło