Differences between ExpandoObject, DynamicObject and dynamic
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
dynamic, ExpandoObject, and DynamicObject are related in C#, but they are not interchangeable. dynamic is a language feature that postpones member binding until runtime, ExpandoObject is a ready-made dynamic object whose members can be added at runtime, and DynamicObject is a base class for implementing your own custom dynamic behavior.
The easiest way to keep them straight is to remember that only two of them are object models. dynamic is not a container type. It changes how the compiler treats an expression.
dynamic Is A Binding Mode
The dynamic keyword tells the compiler not to perform its normal static member checks for that expression:
This compiles because the actual member lookup is deferred to runtime. If the object does not support the requested member, the program fails at runtime with a binder error instead of at compile time.
So dynamic is about binding semantics, not about what kind of object you stored.
ExpandoObject Is A Dynamic Bag Of Members
ExpandoObject is a concrete type in .NET that lets you add and remove members dynamically:
This is useful when you need a lightweight object with flexible shape, such as ad hoc view-model data or simple JSON-like objects.
Under the hood, ExpandoObject also behaves like a dictionary of member names and values, which makes it convenient when the set of properties is not known in advance.
DynamicObject Is For Custom Rules
DynamicObject is different. It is a base class you inherit from when you want to define how dynamic access should behave:
This approach is appropriate when you want validation, computed members, logging, proxying, or a backing store that is more complex than a simple property bag.
How They Fit Together
These three ideas often appear together:
- '
dynamiccan reference anExpandoObject' - '
dynamiccan reference an instance of aDynamicObjectsubclass' - '
dynamiccan also reference an ordinary object'
That is why comparing them as if they were sibling types can be misleading. A more accurate description is:
- '
dynamicchanges member resolution behavior' - '
ExpandoObjectgives you a built-in dynamic data object' - '
DynamicObjectlets you define your own dynamic semantics'
When To Use Which One
Use dynamic when you need runtime binding for an object whose shape is not known statically. Use ExpandoObject when you want a flexible object without writing custom behavior. Use DynamicObject when you want full control over how dynamic member access behaves.
If a normal strongly typed class will do the job, it is usually the better choice. Strong typing improves refactoring, tooling, and compiler feedback.
Common Pitfalls
The biggest mistake is thinking dynamic is a replacement for ExpandoObject or DynamicObject. It is not. It is a keyword that affects how C# resolves members.
Another pitfall is overusing dynamic code where a normal class would be clearer and safer. You lose compile-time checking, which increases the chance of runtime errors.
A third issue is choosing DynamicObject when ExpandoObject would already be sufficient. If you just need a flexible property bag, the built-in type is simpler.
Summary
- '
dynamicis a language feature that defers binding to runtime.' - '
ExpandoObjectis a built-in dynamically extensible object.' - '
DynamicObjectis a base class for implementing custom dynamic behavior.' - '
dynamiccan be used with either of those object models or with ordinary objects.' - Prefer strong typing unless runtime flexibility is genuinely required.

