如何将包含两层foreach循环的迭代器拆分为两个独立函数
实现拆分&优化方案
你当前用Concat拼接序列的方案可以正常运行,符合需求,还有两种更优的实现方式:
方案1:嵌套yield返回(性能最优,和原逻辑完全等价)
直接在遍历子项的函数中,枚举单个子项返回的字符串序列,逐个yield返回,既保持延迟执行特性,也不会产生额外的迭代器包装开销:
private IEnumerable<string> GetSubKeysStringValues(RegistryKey key) { foreach (var subKey in GetAllSubKeys(key)) { foreach (var strValue in GetKeysStringValues(subKey)) { yield return strValue; } } } private IEnumerable<string> GetKeysStringValues(RegistryKey key) { foreach (var value in key.GetValueNames()) { if (key.GetValueKind(value) == RegistryValueKind.String) { yield return (string) key.GetValue(value); } } }
方案2:Linq SelectMany 简化写法
如果接受使用Linq,可以用SelectMany直接扁平化嵌套的IEnumerable<IEnumerable<string>>序列,代码更简洁:
using System.Linq; private IEnumerable<string> GetSubKeysStringValues(RegistryKey key) { return GetAllSubKeys(key).SelectMany(subKey => GetKeysStringValues(subKey)); } private IEnumerable<string> GetKeysStringValues(RegistryKey key) { foreach (var value in key.GetValueNames()) { if (key.GetValueKind(value) == RegistryValueKind.String) { yield return (string) key.GetValue(value); } } }
原Concat方案的优化点说明
你当前用循环拼接Concat的实现,在子项数量较多时会生成多层迭代器包装链,遍历的开销会比上述两种方案更高。如果子项规模很小可以忽略差异,否则更推荐使用上述两种实现。
内容的提问来源于stack exchange,提问作者Milan
相关产品推荐
相关产品推荐

