当前位置: 首页 > news >正文

.NET ExpandoObject 技术原理解析

🌟 .NET ExpandoObject 技术原理解析

引用

  1. .NET 剖析4.0上ExpandoObject动态扩展对象原理
  2. 风潇潇人渺渺
  3. 快意刀山中草
ExpandoObject
IDynamicMetaObjectProvider
IEnumerable
字段_dict
IDictionary
嵌套类ExpandoMetaObject
DynamicMetaObject
方法Set/Get/Invoke
绑定方法BindGetMember等
反射方法缓存

🧠 一、总体架构设计(核心组件分析)

1.1 类关系拓扑图

创建
继承
实现
实现
«sealed»
ExpandoObject
+IDictionary _dict
+IDynamicMetaObjectProvider.GetMetaObject()
+IEnumerable.GetEnumerator()
+IEnumerable.GetEnumerator()
ExpandoMetaObject
-IDictionary dict
+BindGetMember(GetMemberBinder) : DynamicMetaObject
+BindSetMember(SetMemberBinder, DynamicMetaObject) : DynamicMetaObject
+BindInvokeMember(InvokeMemberBinder, DynamicMetaObject[]) : DynamicMetaObject
-Get(string, object) : object
-Set(string, object) : object
-Invoke(string, object) : object
«abstract»
DynamicMetaObject
+Expression Expression
+BindingRestrictions Restrictions
+object Value
+BindGetMember(GetMemberBinder) : DynamicMetaObject
+BindSetMember(SetMemberBinder, DynamicMetaObject) : DynamicMetaObject
+BindInvokeMember(InvokeMemberBinder, DynamicMetaObject[]) : DynamicMetaObject
IDynamicMetaObjectProvider
IEnumerable<string>

1.2 核心数据流架构

数据存储
执行层
DLR层
用户层
属性访问
属性设置
方法调用
Dict读写
线程同步
最终结果
构建表达式树
创建DynamicMetaObject
DLR执行引擎
实际调用Set/Get/Invoke
操作字典数据
GetMemberBinder
SetMemberBinder
InvokeMemberBinder
ExpandoMetaObject.BindGetMember
ExpandoMetaObject.BindSetMember
ExpandoMetaObject.BindInvokeMember
操作类型
动态操作

🛠 二、动态绑定机制深度解析

2.1 元对象提供器实现原理

DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression express)
{return new ExpandoMetaObject(this, express);
}
DLR运行时ExpandoObjectExpandoMetaObject请求MetaObject(Expression)创建ExpandoMetaObject(this, express)返回ExpandoMetaObject实例调用绑定方法(BindGetMember等)返回DynamicMetaObject(表达式树)编译执行表达式树DLR运行时ExpandoObjectExpandoMetaObject

2.2 表达式树构建技术

绑定方法
InvokeMember调用
创建表达式树
Expression.Call
目标对象: this
方法: Set/Get/Invoke
参数1: key常量
参数2: value常量

实际表达式树创建代码:

private DynamicMetaObject InvokeMember(string key, MethodInfo met, params object[] values)
{// 参数处理逻辑object args = null;if (met == invoke) args = values;else if (values != null && values.Length > 0) args = values[0];// 构建表达式树核心return new DynamicMetaObject(Expression.Call(Expression.Constant(this),  // 目标对象met,                        // 方法信息Expression.Constant(key, typeof(string)), // 成员名Expression.Convert(Expression.Constant(args), typeof(object)) // 值),BindingRestrictions.GetTypeRestriction(base.Expression, base.LimitType));
}

🔍 三、成员操作深度分析

3.1 属性获取机制(Get)

用户代码DLR运行时ExpandoMetaObject字典_dictvar value = obj.NameBindGetMember("Name")调用InvokeMember("Name", getMethod)返回表达式树编译并执行表达式树调用Get("Name", null)lock(_dict)返回dict["Name"]抛出MemberAccessExceptionalt[存在键][不存在键]返回结果返回value用户代码DLR运行时ExpandoMetaObject字典_dict

3.2 属性设置机制(Set)

在这里插入图片描述

3.3 方法调用机制(Invoke)

调用Invoke方法
成员存在?
检查类型
检查
BindInvokeMember
参数转换:
收集所有参数
参数转换
InvokeMember:
传递方法名和参数
InvokeMember
构建表达式树
返回DynamicMetaObject
执行表达式树
获取锁
检查成员存在
存在
获取值
不存在
抛出异常
是委托?
是:
动态调用
否:
抛MethodAccessException
DynamicInvoke
返回结果

🔒 四、线程安全与锁机制

4.1 锁的应用全景图

潜在问题
安全访问
锁保护区域
返回原始迭代器
在枚举期间修改字典可能导致异常
临界区操作
字典存在检查
键值读取
键值设置
委托获取
键集合枚举
lock(_dict)
Get操作
Set操作
Invoke操作
枚举操作

4.2 改进后的锁策略

01234567891011121314151617181920字典操作 锁保护 反射方法缓存 枚举器快照 枚举安全 无锁字典 减少锁范围 委托缓存 原始实现优化建议关键改进点线程安全优化方案

改进后枚举实现:

IEnumerator<string> IEnumerable<string>.GetEnumerator()
{lock (_dict){// 创建副本保证线程安全return new List<string>(_dict.Keys).GetEnumerator();}
}

⚡ 五、性能优化深度分析

5.1 反射优化策略

原始实现
每次绑定调用GetMethod
运行时反射
高开销
优化建议
静态构造函数预加载
MethodInfo缓存
减少运行时开销
private static class MethodCache
{public static readonly MethodInfo SetMethod;public static readonly MethodInfo GetMethod;public static readonly MethodInfo InvokeMethod;static MethodCache(){SetMethod = typeof(ExpandoMetaObject).GetMethod("Set", BindingFlags.NonPublic | BindingFlags.Instance);// ...同理缓存其他方法}
}

5.2 表达式树编译缓存

第一次调用
构建表达式树
编译为委托
执行委托
后续调用
使用缓存委托

5.3 内存占用分析

45%25%15%10%5%内存占用分布字典存储表达式树元数据开销委托对象其他

🆚 六、与官方实现对比分析

6.1 架构差异对比图

mindmaproot((架构差异))线程同步🟢 此实现:全局lock🔵 官方实现:无锁CAS成员枚举🔴 此实现:原始迭代器🟢 官方实现:键集合快照元数据处理🟠 此实现:每次构建🟢 官方实现:缓存优化动态方法🟢 两者相同:基于委托错误处理🟠 此实现:基本异常🟢 官方实现:详细异常信息

6.2 性能基准对比

在这里插入图片描述


🛡 七、最佳实践与安全性

7.1 线程安全使用模式

只读线程
读写线程
创建ExpandoObject
写入初始化数据
多线程访问
安全
外部同步
使用外部锁
避免嵌套锁

7.2 异常处理体系

«异常体系»
DynamicExceptions
+MemberAccessException: 成员不存在
+MethodAccessException: 非委托调用
+TargetInvocationException: 委托异常
+InvalidOperationException: 枚举修改
MemberAccessException
MethodAccessException
TargetInvocationException
InvalidOperationException

🔮 八、高级应用场景

8.1 动态工作流引擎集成

条件满足
条件不满足
JSON配置
解析为ExpandoObject
动态添加方法
创建工作流
执行步骤
判断条件
执行下一节点
执行备选分支

8.2 动态规则引擎实现

用户规则API规则引擎ExpandoObject定义规则({condition: "Age >= 18", action: "Approve"})添加规则(规则对象)提交请求(用户数据)转换为动态对象添加验证方法条件结果执行对应操作alt[条件验证]返回结果loop[执行规则]用户规则API规则引擎ExpandoObject

💎 九、总结与展望

9.1 技术实现矩阵

在这里插入图片描述

9.2 未来发展建议

-.NET Core优化=等this[key]访问分段锁策略基于ImmutableDictionary支持+缓存MethodInfo返回快照预编译动态方法
基础优化
基础优化
缓存MethodInfo
反射优化
反射优化
返回快照
枚举安全
枚举安全
分段锁策略
减少锁竞争
减少锁竞争
高级特性
高级特性
this[key]访问
索引器支持
索引器支持
支持+-=等
动态操作符
动态操作符
.NET Core优化
跨平台兼容
跨平台兼容
性能突破
性能突破
基于ImmutableDictionary
无锁实现
无锁实现
预编译动态方法
AOT支持
AOT支持
ExpandoObject进化路线
http://www.dtcms.com/a/278996.html

相关文章:

  • LeetCode经典题解:206、两数之和(Two Sum)
  • OV-DINO:基于语言感知选择性融合的统一开放词汇检测
  • 深入解析ThreadLocal:线程隔离利器
  • C#自定义控件
  • c# 深度解析:实现一个通用配置管理功能,打造高并发、可扩展的配置管理神器
  • Typecho加密文章HTML结构自定义完全指南
  • 在 Windows 主机和 VMware 虚拟机中的 Ubuntu 系统之间实现复制粘贴,
  • Spring IoC 容器实战:从解耦到集成的 6 大核心应用场景
  • 【PTA数据结构 | C语言版】字符串插入操作(不限长)
  • 微前端框架深度对决:qiankun、micro-app、wujie 技术内幕与架构选型指南
  • Ubuntu-25.04 Wayland桌面环境安装Anaconda3之后无法启动anaconda-navigator问题解决
  • 如何降低AIGC的查重率?精选六个AIGC降重让论文更出色
  • Spring Boot项目结构解析:构建高效、清晰的代码框架
  • 【Python进阶】深度复制——deepcopy
  • STM32F1_Hal库学习EXTI
  • 苍穹外卖学习指南(java的一个项目)(老师能运行,但你不行,看这里!!)
  • 最近要上Android 15的高通平台,按照之前Android14的高通平台的裁剪APP的方法修改,发现一改编译之后就不能进系统
  • LLaMA.cpp HTTP 服务参数: --pooling 嵌入模型 池化类型详解
  • 笔试——Day7
  • Datawhale AI夏令营大模型 task2.1
  • QML 常用控件(二)
  • Qt小组件 - 3 imageLabel
  • 【CV综合实战】基于深度学习的工业压力表智能检测与读数系统【3】使用OpenCV读取分割后的压力表读数
  • 《C++内存泄漏8大战场:Qt/MFC实战详解 + 面试高频陷阱破解》
  • 机器学习中的朴素贝叶斯(Naive Bayes)模型
  • AI日报 - 2025年07月14日
  • 认识下计算机视觉中的人脸识别
  • 网络准入控制系统的作用解析,2025年保障企业入网安全第一道防线
  • 【邀请函】网易灵动露天矿山具身智能技术发布会,7月26日上海见
  • 【笔记】chrome 无法打开特定协议或访问特定协议时卡死