何时在C#中使用延迟评估

时间:2017-08-09 15:31:39

标签: c# linq lazy-evaluation

我在C#中编写一个模块,这是一个" sync"从外部系统检索数据的过程,将其与DB中已有的数据进行比较,然后更新数据库。一次涉及多个实体,匹配过程并不简单,并且在列表之间涉及大量的改组和过滤。

在尝试OO实现失败后,我重新设计了所有实体类不可变,并使用了" functional"有很多lambda表达式的风格。我发现它非常适合问题域,代码更具可读性。但是,当我在调试器中运行它时,我发现它非常可怕并且担心副作用 - 例如,我构造了一个从数据库返回的IEnumerable对象,但它们并不是物理检索,直到我枚举列表,到那时数据库可能已更新。

我意识到从数据库中检索一个对象并不是一个纯粹的功能操作,但是我希望我能把它当作一个更干净的代码来处理它。就像它一样。

我的直觉是使用" ToList()"它似乎可以解决问题(并且还可以摆脱resharper"可能的多次枚举"警告),但这看起来有点像作弊。

我已经阅读过关于懒惰评估的内容但主要是他们在纯函数代码的上下文中解释这些概念,而且当涉及外部依赖关系时,我没有看到关于如何使用它的警告的任何内容

在一个非平凡的代码库中,有一种简单的方法来决定懒惰评估可能有害吗?或者更好的方法来解决有副作用的功能引起的问题?

1 个答案:

答案 0 :(得分:0)

何时使用延迟评估?

  1. 使用它来推迟对实际使用该对象的某些内容的评估/实例化,通常是在评估/实例化成本并且该对象可能根本不被使用时。
  2. 使用它来降低提取一组大小为N的前M个项目的成本,其中N>> M.使用迭代器,您只需要支付检索/生成N个项目的成本,而不是首先是所有M个项目,然后选择第一个N.
  3. 在您的情况下,您似乎需要在任何客户端使用它之前检索您的数据库对象,因为您希望所有客户端访问的数据保持一致/相同。在这种情况下,这意味着您要么在分发之前评估您的Enumerable,要么以这样的方式分发它:在第一次评估之后,这样做的所有其他客户端将访问相同的数据。