在两个不同的函数中拆分包含两个 foreach 循环的迭代器
Split an Iterator containing two foreach loops in two different functions
我有当前函数:
private IEnumerable<string> GetKeysStringValues(RegistryKey key)
{
foreach (var subKey in GetAllSubKeys(key))
{
foreach (var value in subKey.GetValueNames())
{
if (subKey.GetValueKind(value) == RegistryValueKind.String)
{
yield return (string) subKey.GetValue(value);
}
}
}
}
它:
- 解析注册表项的所有子项
- 对于每个子项,解析其所有值
- 如果值为字符串,则将其添加到迭代器
我担心的是有两个嵌入式 for-each 循环,我一点也不喜欢。
我想把这个功能一分为二。
问题是我最终得到了 return 类型的 IEnumerable<IEnumerable<string>>
我试图只在第二个函数中构建迭代器,并在第一个函数中直接 return 它,但是这样做我错过了所有后续调用。
这是导致它的代码:
private IEnumerable<IEnumerable<string>> GetSubKeysStringValues(RegistryKey key)
{
IEnumerable<string> enumerable = Enumerable.Empty<string>();
foreach (var subKey in GetAllSubKeys(key))
{
yield return 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);
}
}
}
你会怎么做?
编辑:
到目前为止我有这个解决方案,但它可以改进吗?
private IEnumerable<string> GetSubKeysStringValues(RegistryKey key)
{
IEnumerable<string> enumerable = Enumerable.Empty<string>();
foreach (var subKey in GetAllSubKeys(key))
{
enumerable = enumerable.Concat(GetKeysStringValues(subKey));
}
return enumerable;
}
private IEnumerable<string> GetKeysStringValues(RegistryKey key)
{
foreach (var value in key.GetValueNames())
{
if (key.GetValueKind(value) == RegistryValueKind.String)
{
yield return (string) key.GetValue(value);
}
}
}
I have this solution so far, but could it be improved ?
你的解决方案很好。如果您想要更紧凑的代码,可以使用 LINQ 方法 SelectMany
,其目的是将 IEnumerable<IEnumerable<T>>
“扁平化”为 IEnumerable<T>
:
private IEnumerable<string> GetSubKeysStringValues(RegistryKey key)
{
return GetAllSubKeys(key).SelectMany(subKey => GetKeysStringValues(subKey));
}
...或者,如果您更喜欢查询语法(产生相同的结果,甚至可能产生相同的 IL 代码):
private IEnumerable<string> GetSubKeysStringValues(RegistryKey key)
{
return from subKey in GetAllSubKeys(key)
from value in GetKeysStringValues(subKey)
select value;
}
我有当前函数:
private IEnumerable<string> GetKeysStringValues(RegistryKey key)
{
foreach (var subKey in GetAllSubKeys(key))
{
foreach (var value in subKey.GetValueNames())
{
if (subKey.GetValueKind(value) == RegistryValueKind.String)
{
yield return (string) subKey.GetValue(value);
}
}
}
}
它:
- 解析注册表项的所有子项
- 对于每个子项,解析其所有值
- 如果值为字符串,则将其添加到迭代器
我担心的是有两个嵌入式 for-each 循环,我一点也不喜欢。 我想把这个功能一分为二。
问题是我最终得到了 return 类型的 IEnumerable<IEnumerable<string>>
我试图只在第二个函数中构建迭代器,并在第一个函数中直接 return 它,但是这样做我错过了所有后续调用。
这是导致它的代码:
private IEnumerable<IEnumerable<string>> GetSubKeysStringValues(RegistryKey key)
{
IEnumerable<string> enumerable = Enumerable.Empty<string>();
foreach (var subKey in GetAllSubKeys(key))
{
yield return 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);
}
}
}
你会怎么做?
编辑:
到目前为止我有这个解决方案,但它可以改进吗?
private IEnumerable<string> GetSubKeysStringValues(RegistryKey key)
{
IEnumerable<string> enumerable = Enumerable.Empty<string>();
foreach (var subKey in GetAllSubKeys(key))
{
enumerable = enumerable.Concat(GetKeysStringValues(subKey));
}
return enumerable;
}
private IEnumerable<string> GetKeysStringValues(RegistryKey key)
{
foreach (var value in key.GetValueNames())
{
if (key.GetValueKind(value) == RegistryValueKind.String)
{
yield return (string) key.GetValue(value);
}
}
}
I have this solution so far, but could it be improved ?
你的解决方案很好。如果您想要更紧凑的代码,可以使用 LINQ 方法 SelectMany
,其目的是将 IEnumerable<IEnumerable<T>>
“扁平化”为 IEnumerable<T>
:
private IEnumerable<string> GetSubKeysStringValues(RegistryKey key)
{
return GetAllSubKeys(key).SelectMany(subKey => GetKeysStringValues(subKey));
}
...或者,如果您更喜欢查询语法(产生相同的结果,甚至可能产生相同的 IL 代码):
private IEnumerable<string> GetSubKeysStringValues(RegistryKey key)
{
return from subKey in GetAllSubKeys(key)
from value in GetKeysStringValues(subKey)
select value;
}