我得为我开始实现缓存的想法:
Memoizing功能 S和存储与函数签名的散列沿返回速度 。 使用PostSharp ,我要检查缓存并返回返回值的水化表示,而不是再次调用该函数。 我想使用属性来控制此行为。
不幸的是,这可能是危险的其他开发商在我的组织,如果他们爱上的性能增益,并开始装饰每一个方法在视线与缓存的属性,包括一些副作用 。 我想踢走一个编译器警告时,记忆化图书馆犯罪嫌疑人,一个功能可能会引起副作用。
我怎样才能知道这些代码可能会引起副作用,使用的CodeDOM或反射?
我得为我开始实现缓存的想法:
Memoizing功能 S和存储与函数签名的散列沿返回速度 。 使用PostSharp ,我要检查缓存并返回返回值的水化表示,而不是再次调用该函数。 我想使用属性来控制此行为。
不幸的是,这可能是危险的其他开发商在我的组织,如果他们爱上的性能增益,并开始装饰每一个方法在视线与缓存的属性,包括一些副作用 。 我想踢走一个编译器警告时,记忆化图书馆犯罪嫌疑人,一个功能可能会引起副作用。
我怎样才能知道这些代码可能会引起副作用,使用的CodeDOM或反射?
这是一个非常困难的问题,无论是在实践上和理论上。 我们正在认真思考的方式来防止或隔离副作用正是您的场景-记忆化, 自动并行化 ,等等-但它是困难的,我们还远从C#一个可行的解决方案。 所以,没有承诺。 (考虑改用Haskell的,如果你真的想消除副作用)。
不幸的是,即使奇迹发生了,你找到了一种方法,以防止副作用的方法记忆化,你仍然有一些大的问题。 考虑以下:
1)如果你memoize的一个函数,它本身就是调用一个函数memoized? 这是一个良好的局面是,对不对? 你想成为能够撰写memoized功能。 但是,记忆化有一个副作用:它增加了数据缓存! 所以,你马上有一个元问题:你想驯服的副作用,但只有“坏”的副作用。 你想要的“好”的人鼓励,要防止坏的,这是很难区分它们。
2)你打算怎么办例外? 您可以memoize的该抛出异常的方法? 如果是这样,它总是抛出同样的异常,或每次它抛出一个新的异常? 如果是前者,你打算怎么办呢? 如果是后者,你现在有一个memoized函数有两个不同的调用两种不同的结果,因为两个不同的抛出异常。 异常可以被看作是一个副作用; 这是很难驯服例外。
3)你打算做哪些没有副作用,但仍然是不纯的方式方法呢? 假设你有一个方法GetCurrentTime()。 不具有副作用; 什么是呼叫突变。 但是,这仍然不是一个候选人memoization的,因为任何两个调用都需要产生不同的结果。 你并不需要一个副作用探测器,你需要的纯度检测。
我认为最好的办法是通过教育和代码审查,以解决人类的问题,而不是试图解决难的技术问题。
简单地说你不能用任何的CodeDOM或反射。
要准确判断的方法是否会产生副作用,你必须了解它正在采取什么行动。 对于.NET那意味着裂化开放IL和以某种方式interperting它。
无论是反射或CodeDom中给你这个能力。
反思本身不会做,因为元数据不具有任何这样的属性。
CodeDom中可能没有强大到足以检查所有的IL指令。
所以,你必须使用反射API,让你得到一个非常低级别的作品byte[]
包含每个方法的原始IL,并分析。 所以这是可能的原则,但并不容易。
你必须分析所有的指令和观察他们有什么影响,以及这些影响是否要一些显著范围之外生存(如不修改,他们可以通过返回值或泄漏对象的领域out
参数,或不,他们只是修改,保证不可达的方法以外的临时对象?)。
听起来很复杂!