Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 缓存IEnumerable vs列表以进行延迟初始化_C#_.net_Linq_Caching - Fatal编程技术网

C# 缓存IEnumerable vs列表以进行延迟初始化

C# 缓存IEnumerable vs列表以进行延迟初始化,c#,.net,linq,caching,C#,.net,Linq,Caching,我有一个简单的缓存类,用于检索和存储传递给它的任何数据。此类仅有的操作是“获取(字符串键)”和“存储(字符串键,对象数据)”。我使用这个类来存储昂贵的对象并快速检索它们 假设我要存储一个数组。据我所知,IEnumerable实现本质上是惰性实例化的。我的问题是:如果我将一个IEnumerable变量存储到该缓存类(即LINQ查询的结果集),该类是否会被存储并处理其所有元素,或者每次我检索存储的IEnumerable时,我都必须经过所有隐含的处理来生成该IEnumerable?我应该使用“ToLi

我有一个简单的缓存类,用于检索和存储传递给它的任何数据。此类仅有的操作是“获取(字符串键)”和“存储(字符串键,对象数据)”。我使用这个类来存储昂贵的对象并快速检索它们

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


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

IEnumerable是一个接口,而不是一个类。接口背后的实现定义了其行为

如果对IEnumerable调用ToList(),则会得到一个列表,但也会得到一个IEnumerable,因为该列表实现了该接口

将指针存储为IEnumerable并对其进行迭代与对列表进行迭代相同

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

例如: 执行以下功能:

public IEnumerable<int> Generator(int max)
{
   for (var i = 0; i < max; i++)
   {
       yield return someExpensiveFunction();
   }
}
公共IEnumerable生成器(int max)
{
对于(变量i=0;i
将其用作

var cache = Generator(100);

for (var i = 0; i < 2; i++)
{
   foreach (var i in cache)
   {
      //ops
   }
}
var缓存=生成器(100);
对于(变量i=0;i<2;i++)
{
foreach(缓存中的变量i)
{
//老年退休金
}
}
这将对生成器(=IEnumerable)求值两次

var cache=Generator(100).ToList();
对于(var i=0;i<2;i++
{
foreach(缓存中的变量i)
{
//老年退休金
}
}
这将只对生成器(=IENumerable)求值一次

例如,如果通过调用ToArray()、ToList()等使IEnumerable“具体化”,则缓存IEnumerable并不昂贵

Dome附加指南。如果将可枚举项转换为列表并存储,最好将存储变量声明为列表。这将向用户和/或同事记录其存储模型。 公共类/接口上的函数或属性的结果应为集合

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); }
   }
}
X类
{
私有列表缓存;
公共无效更新缓存(IEnumerable items)
{
_cache=items.ToList();
}
公共ICollection缓存
{
获取{return\u cache;}
}
//更好
公共只读集合项目
{
获取{返回新的只读集合(_缓存);}
}
}

这个简单的缓存与字符串、对象的字典有什么不同。为了澄清,这意味着在没有.List()的情况下调用Generator,您在Generator函数中调用了两次循环?我的意思是,举例来说,Generator函数总共有200次迭代?如果您为(var i=0;i<4;i++)”,总共会有400次迭代?我认为收益率返回延迟执行,这样您就不会执行不必要的操作,如果我没有弄错的话,那么所有内容都将存储并处理在该变量中。
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); }
   }
}