c# - 懒惰地检索用作 IEnumerable 的数组
问题描述
我可以访问一个公开数组的 API T
,即有一个签名
T[] Get();
我正在创建一个对T
s 执行计算并生成的 API T2
。每次调用 to都是昂贵的,而从to的Get()
每个投影都是昂贵的。我可能不需要所有的 s,所以我想公开:T
T2
T2
IEnumerable<T2> GetProjected();
现在,我意识到没有什么可以让我变得Get()
懒惰。我将需要检索整个数组。但是,我希望能够在没有立即导致被调用的情况下调用GetProjected()
并获得一个。换句话说,以下两种实现是不好的:IEnumerable<T2>
Get()
public IEnumerable<T2> GetProjected()
{
var items = _api.Get(); // bad!
return items.Select(t => ProjectToT2(t));
}
public IEnumerable<T2> GetProjected2()
{
var items = new Lazy<IEnumerable<T>(() => _api.Get());
return items
.Value // bad again!
.Select(t => ProjectToT2(t));
}
你可能会看到我要去哪里。如何在IEnumerable<T2>
不引起立即调用的情况下公开一个Get()
?我必须实现自定义IEnumerator<T2>
和IEnumerable<T2>
配对吗?
解决方案
使用迭代器方法:
public IEnumerable<T2> GetProjected()
{
var results = api.Get()
.Select(t => ProjectToT2(t));
foreach(var x in results)
{
yield return x;
}
}
由于 的签名,您无法绕过在一个完整块中检索的数组Get()
,但是这样只有在枚举 的结果时才会调用它GetProjected()
,例如,如果您调用ToArray()
它,而不是使用Select()
or Where
。
推荐阅读
- python - 如何使用 Pyautogui 输入特殊字母
- git - TortoiseGit 从所有分支中拉出不考虑远程分支
- python - Python:找到最大值
- c# - 使用 WCF 打开或呈现局部视图
- python - 如何增加 OpenCV、tkinter 和枕头的 FPS
- node.js - 多个 API 使用节点 js 生成一个数组/对象
- php - PHP 7.0 到 7.2 更新到 7.4
- c - 在C中将数组转换为矩阵
- javascript - 使用 JS 的无限滚动无法在 Chrome 浏览器上运行 - PURE JS
- php - 如何在 PHP Linux 中访问 .mdb 数据源?