What are the differences between System.Dynamic.ExpandoObject
, System.Dynamic.DynamicObject
and dynamic
?
In which situations do you use these types?
What are the differences between System.Dynamic.ExpandoObject
, System.Dynamic.DynamicObject
and dynamic
?
In which situations do you use these types?
According to the C# language specification
dynamic
is a type declaration. I.e.dynamic x
means the variablex
has the typedynamic
.DynamicObject
is a type that makes it easy to implementIDynamicMetaObjectProvider
and thus override specific binding behavior for the type.ExpandoObject
is a type that acts like a property bag. I.e. you can add properties, methods and so forth to dynamic instances of this type at runtime.The
dynamic
keyword is used to declare variables that should be late-bound.If you want to use late binding, for any real or imagined type, you use the
dynamic
keyword and the compiler does the rest.When you use the
dynamic
keyword to interact with a normal instance, the DLR performs late-bound calls to the instance's normal methods.The
IDynamicMetaObjectProvider
interface allows a class to take control of its late-bound behavior.When you use the
dynamic
keyword to interact with anIDynamicMetaObjectProvider
implementation, the DLR calls theIDynamicMetaObjectProvider
methods and the object itself decides what to do.The
ExpandoObject
andDynamicObject
classes are implementations ofIDynamicMetaObjectProvider
.ExpandoObject
is a simple class which allows you to add members to an instance and use themdynamic
ally.DynamicObject
is a more advanced implementation which can be inherited to easily provide customized behavior.The above example of
DynamicObject
does not tell the difference clearly, because it's basically implementing the functionality which is already provided byExpandoObject
.In the two links mentioned below, it is very clear that with the help of
DynamicObject
, it is possible to preserve/change the actual type (XElement
in the example used in below links) and better control on properties and methods.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/
I will try to provide a clearer answer to this question, to explain clearly what the differences are between dynamic,
ExpandoObject
andDynamicObject
.Very quickly,
dynamic
is a keyword. It is not a type per-se. It is a keyword that tells the compiler to ignore static type checking at design-time and instead to use late-binding at run-time. So we're not going to spend much time ondynamic
in the rest of this answer.ExpandoObject
andDynamicObject
are indeed types. On the SURFACE, they look very similar to each other. Both classes implementIDynamicMetaObjectProvider
. However, dig deeper and you'll find they're NOT similar at all.DynamicObject is a partial implementation of
IDynamicMetaObjectProvider
purely meant to be a starting point for developers to implement their own custom types supporting dynamic dispatch with custom underlying storage and retrieval behavior to make dynamic dispatch work.In short, use DynamicObject when you want to create your OWN types that can be used with the DLR and work with whatever CUSTOM behaviors you'd like.
Example: Imagine that you'd like to have a dynamic type that returns a custom default whenever a get is attempted on a member that does NOT exist (i.e. has not been added at run time). And that default will say, "I'm sorry, there are no cookies in this jar!". If you want a dynamic object that behaves like this, you'll need to control what happens when a field is not found. ExpandoObject will not let you do this. So you'll need to create your own type with unique dynamic member resolution (dispatch) behavior and use that instead of the ready-built
ExpandoObject
.You can create a type as follows: (Note, the below code is just for illustration and may not run. To learn about how to properly use DynamicObject, there are many articles and tutorials elsewhere.)
Now, we could use this imaginary class we just created as a dynamic type that has a very custom behavior if the field doesn't exist.
ExpandoObject
is a FULL implementation ofIDynamicMetaObjectProvider
, where the .NET Framework team has made all of these decisions for you. This is useful if you don't need any custom behavior, and you feel that ExpandoObject works good enough for you (90% of the time,ExpandoObject
is good enough). So for example, see the following, and that for ExpandoObject, the designers chose to throw an exception if the dynamic member does not exist.So to summarize,
ExpandoObject
is simply one pre-chosen way to extend DynamicObject with certain dynamic dispatch behaviors that will probably work for you, but may not depending on your particular needs.Whereas,
DyanmicObject
is a helper BaseType that makes implementing your own types with unique dynamic behaviors simple and easy.A useful tutorial on which much of the example source above is based.