如果是能简单解决的问题,就不用想得太复杂了
2009-09-05 17:41 Jeffrey Zhao 阅读(7560) 评论(34) 编辑 收藏 举报有个朋友在MSN问我说,有没有关于Emit的资料,它想生成一个类的动态代理。他抱怨Emit还是很麻烦,不过交谈过后知道他是想要做什么。他希望为一个对象的某个属性作延迟加载,这样可以避免一些无谓的消耗。例如:
public class SomeClass { public int SomeID { get; set; } // some other members... }
原本构造一个SomeClass时可以这样:
var someClass = new SomeClass(); someClass.SomeID = GetSomeID(); Process(someClass);
但是由于Process方法中可能不需要用到SomeID属性,于是在外部调用的GetSomeID方法可能就形成了无谓的性能损耗。一个常见的做法方式可能就是进行延迟加载了。那位朋友的意思是先把SomeID标为virtual:
public class SomeClass { public virtual int SomeID { get; set; } // some other members... }
然后使用Emit来生成一个动态类型,继承SomeClass,override掉SomeID属性,形成延迟加载。不过我提出,这个方法是不是太重了,因为动态代理不是那么孤立存在的,它往往需要考虑很多其他东西。例如缓存动态类型,例如,对于相同类型一个成员或多个成员的延迟加载,使生成一个通用的动态类型,还是多个动态类型。例如……怎么样的API是最合适的?
所以,如果只是简单的情况下,不如直接手动来实现这样的延迟效果:
public class LazySomeClass : SomeClass { public override int SomeID { get { return this.LazySomeID.Value; } set { this.LazySomeID.Value = value; } } public Lazy<int> LazySomeID { get; set; } }
于是在使用的时候就可以:
var someClass = new LazySomeClass(); someClass.LazySomeID = new Lazy<int>(() => GetSomeID()); Process(someClass);
这样其实就可以在一定程度上达到目的了。Lazy类的原理在之前也有过提及(这里需要些修改),这是一种简单但有用的类型。其实在项目的许多情况下,我们这么做也足够了。不需要复杂的方法,不需要复杂的Emit。不过如果您是为了锻炼能力,或者由于项目中此类需求特别多,想设计一个通用的的类库,这也不错。
当然,上面的实现也有缺陷,因为它不是最理想、最完整、最通用的延迟加载代理类(为什么?)。如果您感兴趣,也可以想象一个完美的代理类应该是什么样子的,甚至给出一个通用的辅助类库。
哦,对了,NHibernate的做法其实也不完美,有机会我会分析一下,并阐述我的看法的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)