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