请解释 C# 中动态对象的概念,并说明通过 ExpandoObject 与 DynamicObject 两种途径实现动态类型的方法与区别。
考察说明
考查对 C# 动态类型机制及其两种典型实现方式的理解与应用能力。
回答思路
- 【回答框架 1】动态对象指在运行时解析成员绑定,而非编译时静态绑定的对象,核心是 DLR(动态语言运行时)支持,常用于与动态语言交互或处理结构灵活的数据。
- 【回答框架 2】ExpandoObject 是 sealed 类,直接实现 IDictionary<string, object?> 与 INotifyPropertyChanged,可像字典一样动态增删属性,适合快速构建数据容器或绑定 UI,性能上反射加 DLR 开销较低。
- 【回答框架 3】DynamicObject 是抽象基类,需继承并重写 TryGetMember、TrySetMember、TryInvokeMember 等方法,可完全自定义成员解析逻辑,适合实现代理、DSL 或高级动态行为,灵活性更高但代码量略大。
- 【回答框架 4】使用场景上,ExpandoObject 适合简单数据聚合,DynamicObject 适合复杂自定义动态语义;二者均要求目标类型为 dynamic 才能触发动态绑定。
- 【回答框架 5】动态类型无法获得编译期类型检查和 IntelliSense,错误延迟到运行时,且与静态类型混用需注意装箱拆箱与性能开销。
- 【关键点 1】动态对象在运行时解析成员,依赖 DLR。
- 【关键点 2】ExpandoObject 以字典实现,适合快速动态数据存储。
- 【关键点 3】DynamicObject 允许自定义成员解析逻辑,适合复杂动态行为。
- 【关键点 4】使用 dynamic 关键字调用动态成员才会触发动态绑定。
- 【关键点 5】动态类型牺牲编译期安全检查,可能引入运行时异常。
- 【易错点 1】误将动态对象当作静态类型使用,导致编译失败或运行时绑定异常。
- 【易错点 2】忽略 ExpandoObject 与 DynamicObject 在性能与灵活性上的取舍,在热点路径使用动态绑定可能产生额外开销。
- 【易错点 3】重写 DynamicObject 方法时未正确处理所有成员类型或返回值,可能导致不预期行为。