c# - 缓存 IEnumerable 与 List 以进行延迟初始化

标签 c# .net linq caching

我有一个简单的缓存类,用于检索和存储您传递给它的任何数据。此类唯一的操作是“Get(string key)”和“Store(string key, object data)”。我使用此类来存储昂贵的对象并快速检索它们。

假设我想存储一个数组。据我所知,IEnumerable 实现本质上是惰性实例化的。我的问题是:如果我将一个 IEnumerable 变量存储到该 Cache 类(即 LINQ 查询的结果集),该类是否会存储其所有已处理的元素,或者每次我检索存储的 IEnumerable 时我都必须完成所有处理暗示生成那个 IEnumerable?我应该使用“ToList()”来触发初始化吗?

注意:我无权访问此缓存类的源代码,我只知道它存储和检索对象。

最佳答案

IEnumerable 是一个接口(interface)而不是一个类。接口(interface)背后的实现定义了它的行为。

如果您在 IEnemerable<> 上调用 ToList(),您会得到一个 List<>,但也会得到一个 IEnumerable<>,因为 List 实现了该接口(interface)。

将指针存储为 IEnumerable<> 并迭代它与迭代列表相同。

如果 IEnumerable<> 是迭代器的结果,则每次访问 IEnumerable<> 时都会执行该实现。

例子: 采取以下功能:

public IEnumerable<int> Generator(int max)
{
   for (var i = 0; i < max; i++)
   {
       yield return someExpensiveFunction();
   }
}

用作

var cache = Generator(100);

for (var i = 0; i < 2; i++)
{
   foreach (var i in cache)
   {
      //ops
   }
}

这将计算生成器 (==IEnumerable<>) 两次。

var cache = Generator(100).ToList();

for(var i = 0; i < 2; i++
{
   foreach(var i in cache)
   {
      //ops
   }
}

这只会对生成器 (==IENumerable<>) 求值一次。

即如果您通过调用 ToArray()、ToList() 等使其“具体”,那么缓存 IEnumerable<> 并不昂贵。

圆顶附加指导。如果将可枚举转换为列表并存储它们,最好将存储变量声明为列表。这是为了向您的用户和/或同事记录它的存储模型。 公共(public)类/接口(interface)上的函数或属性的结果应该是 Collection

class X
{
   private List<int> _cache;

   public void UpdateCache(IEnumerable<int> items)
   {
     _cache = items.ToList();
   }

   public ICollection<T> Cache
   {
      get{ return _cache; }
   }

   //even better
   public ReadOnlyCollection<T> Items
   {
      get { return new ReadonlyCollection(_cache); }
   }
}

关于c# - 缓存 IEnumerable 与 List 以进行延迟初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25530612/

相关文章:

c# - 如何使用 LINQ 和 C# 更新带有列表的元素

c# - 为什么故意不优化这个循环?

c# - 如何在不同线程中处理视频帧(C#)

c# - 通过 ILGenerator 调用带谓词表达式的 LINQ

c# - C# 中的 SQL LIKE 等价物

.net - SQLite 程序集未复制到输出文件夹以进行单元测试

c# - 使用 xaml 在数据网格中选择行后更改 DataGridTemplateColumn 中的复选框状态

c# - 检查发件人是否为@Html.ActionLink

c# - 全局范围内的 .NET session 替代方案

c# - 如何在抽象基类中部分实现契约?