c# - 如何以编程方式检测副作用(编译时或运行时)?

标签 c# memoization side-effects

我有一个缓存的想法,我正在开始实现:

Memoizing function s 并将返回值与函数签名的哈希值一起存储在 Velocity 中.使用 PostSharp ,我想检查缓存并返回返回值的再水化表示,而不是再次调用该函数。我想使用属性来控制这种行为。

不幸的是,这对我组织中的其他开发人员来说可能是危险的,如果他们爱上了性能提升并开始使用缓存属性(包括一些具有副作用)装饰眼前的每个方法。当内存库怀疑某个函数可能会导致副作用时,我想发出编译器警告。

如何使用 CodeDom 或反射来判断代码可能会产生副作用?

最佳答案

无论是在实践上还是理论上,这都是一个极其困难的问题。我们正在认真考虑如何为您的场景精确地预防或隔离副作用——内存,automatic parallelization ,等等——但这很困难,而且我们距离 C# 的可行解决方案还很远。所以,没有 promise 。 (如果你真的想消除副作用,请考虑改用 Haskell。)

不幸的是,即使奇迹发生了并且您找到了一种方法来防止具有副作用的方法内存,您仍然遇到一些问题。请考虑以下事项:

1) 如果您内存一个本身调用内存函数的函数怎么办?这是一个很好的情况,对吧?您希望能够编写内存函数。但是内存有一个副作用:它会将数据添加到缓存中!所以你马上就有了一个元问题:你想驯服副作用,但只是“坏”的副作用。你想鼓励的“好”,你想阻止的坏,很难区分它们。

2) 你打算如何处理异常?你能记住一个抛出异常的方法吗?如果是这样,它总是抛出相同的异常,还是每次都抛出一个新的异常?如果是前者,你打算怎么做?如果是后者,现在你有一个内存函数,它在两个不同的调用上有两个不同的结果,因为抛出了两个不同的异常。异常可以看作是副作用;很难驯服异常。

3) 对于没有副作用但仍然不纯 的方法,您打算怎么办?假设您有一个方法 GetCurrentTime()。那没有副作用;通话不会改变任何内容。但这仍然不是记忆化的候选对象,因为需要任何两次调用才能产生不同的结果。 您不需要副作用检测器,您需要纯度检测器。

我认为最好的办法是通过教育和代码审查来解决人类问题,而不是试图解决困难的技术问题。

关于c# - 如何以编程方式检测副作用(编译时或运行时)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1194898/

相关文章:

python - 高效的通用Python内存

unit-testing - 有没有办法对副作用进行单元测试?

RxJs:如何将两个 observable 组合成一个不同类型的新 observable

checkbox - CListCtrl 带复选框的问题

javascript - 在 TextChanged 或 CheckedChanged 事件上使用 JavaScript 清除两个 TextBox 和 checkBox

c# - filterContext.Cancel 发生了什么(ASP.NET MVC)

javascript - 将参数内存为键

c# - WithDegreeOfParallelism(N>CPU 数量)

c# - 将文件附加到 MailMessage C# 时文件已损坏

optimization - 记或不记