gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 16:10:35 25 4
gpt4 key购买 nike

我有一个简单的缓存类,用于检索和存储您传递给它的任何数据。此类唯一的操作是“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/

25 4 0