Introduction
C#
In-housedynamic
is a special type that allows the type and member of an object to be determined at runtime, rather than at compile time.
Definition of dynamic
-
dynamic
is a type that tells the compiler to "dynamic type parsing" it. -
dynamic
Variables of types skip compile-time type checking, and all operations are postponed to runtime. - Suitable for handling unknown types of objects, or need to be associated with dynamic languages (e.g.
Python
、JavaScript
) Interoperable scenarios.
Use of dynamic
Dynamic type assignment
dynamic obj = 10; // Can be an integerobj = "Hello"; // Can be turned into a stringobj = new { Name = "John", Age = 30 }; // It can also be anonymous
Visit members
Members of dynamic objects are parsed at runtime, so any member can be accessed:
If a non-existent member is accessed, the runtime will be thrownRuntimeBinderException
。
dynamic obj = new { Name = "John", Age = 30 }; (); // Output: John
Dynamic method call
dynamic math = new { Add = (Func<int, int, int>)((x, y) => x + y) }; ((2, 3)); // Output: 5
The core features of dynamic
Differences from compile-time types (static types):
- Compile-time check:
dynamic
The type or member exists at compile time, and all operations are deferred until runtime. - Static type:
object
and other types are type checked at compile time.
object obj1 = 10; // (); // Compilation error: object does not have SomeMethod method dynamic obj2 = 10; // (); // Compiled by,But an exception was thrown at runtime
Type inference
Dynamic types are determined at runtime, while static types are inferred by the compiler:
dynamic dynamicVariable = 123; // The compiler does not check the typeint staticVariable = 123; // The compiler infers it as int object obj = "Hello"; // (); // Compile error(((string)obj).Length); // Cases dynamic dyn = "Hello"; (); // Runtime parsing,Compiled by
Use scenarios
- Interact with dynamic language: calling dynamic languages
API
,likeCOM
Object,IronPython
wait -
JSON
orXML
Data processing: Dynamic parsing when processing data with unknown structures. - Anonymous types and dynamic extensions: Quick access to dynamically created objects.
Things to note
- Performance overhead: Dynamic binding introduces performance overhead because parsing is done at runtime.
- Type safety: Lack of compile-time type checking can lead to runtime errors.
- Debug difficulty: Errors can be difficult to detect, especially in complex scenarios.
ExpandoObject and dynamic
ExpandoObject
Is a dynamic object that dynamically adds or deletes members at runtime:
Often used in scenarios that require flexible expansion, such asJSON
Data parsing
using ; dynamic expando = new ExpandoObject(); = "John"; = 30; ($"{}, {}");
ExpandoObject internal implementation mechanism
ExpandoObject
The following key interfaces are implemented:
-
IDynamicMetaObjectProvider
: Provides core interfaces that dynamic behavior (such as dynamic calls, member access). -
IDictionary<string, object>
: Use a Dictionary internally<string, object>
Store dynamically added members.
using ; dynamic expando = new ExpandoObject(); = "John"; // Dynamically add members(); // Dynamic access to members // Equivalent to:var expando = new ExpandoObject() as IDictionary<string, object>; expando["Name"] = "John"; (expando["Name"]);
How does ExpandoObject achieve dynamicity?
ExpandoObject
Use dynamic binding and meta objects to achieve dynamic behavior:
- Dynamic binding: via
IDynamicMetaObjectProvider
, parsing access requests such as properties, methods, etc. at runtime. - Internal Dictionary: By
Dictionary<string, object>
Store members. - MetaObject:
ExpandoObject
The dynamic behavior of a meta objectExpandoMetaObject
Provides support, it is responsible for interpreting dynamic operations and mapping them to an internal dictionary.
ExpandoObject Thread Safety
-
ExpandoObject
Not thread-safe by nature, as it allows dynamic modification of members. - In multi-threaded scenarios, explicit locking is required to ensure thread safety.
ExpandoObject Usage Example
- Dynamically add/remove members
dynamic expando = new ExpandoObject(); = "John"; = 30; // Delete membersvar dict = (IDictionary<string, object>)expando; ("Age"); // Check members(("Name")); // True (("Age")); // False
- Combined
LINQ
Query
becauseExpandoObject
ImplementedIDictionary<string, object>
, can be combinedLINQ
operate:
dynamic expando = new ExpandoObject(); = "John"; = 30; var dict = (IDictionary<string, object>)expando; var filtered = (kv => ("N")); foreach (var kv in filtered) { ($"{}: {}"); }
Comprehensive consideration
1. Usedynamic
Scenario:
- With external dynamic types (e.g.
COM
, dynamic language) interaction. - Dynamically call methods or access properties without building explicit objects.
- Dynamic behavior is temporarily required, but no dynamic modification of members is required.
2. UseExpandoObject
Scenario:
- Objects that need to be built with dynamic extensions.
- Dynamically add and delete attributes.
- Build a lightweight and flexible business model.
Select a suggestion
characteristic | dynamic | ExpandoObject |
---|---|---|
Dynamic member analysis | Supports any dynamic member, runtime checking during parsing | Only dynamic members that are explicitly added to objects can be operated only |
Dynamic member addition/deletion | Not supported | Support (implemented through dictionary) |
Type Check | No type checking at compile time, runtime parsing | Same runtime parsing |
Suitable scenarios | Dynamic language interoperability, temporary operation, reflection | Dynamically build object and domain model extension |
performance | Slower than static types because of dynamic binding at runtime | More efficient, dictionary-based implementation |
Implement complexity | Dynamic behavior is handled by CLR | Dynamic behavior is implemented by ExpandoObject |
Support for dictionaries | Not supported | Inside is IDictionary<string, object> |
Security | There are many errors at runtime and complex debugging | Dynamic but with certain constraints |
Summarize
The above is personal experience. I hope you can give you a reference and I hope you can support me more.