在两个不同的函数中拆分包含两个foreach循环的Iterator



我有当前的功能:

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);
}
}
}
}

它:

  1. 分析注册表项的所有子项
  2. 对于每个子键,解析其所有值
  3. 如果值是字符串,则将其添加到迭代器

我担心的是每个循环都嵌入了两个,我一点也不喜欢。我想把这个函数一分为二。

问题是,我最终得到的返回类型是IEnumerable<IEnumerable<string>>

我试图只在第二个函数中构建Iterator,并在第一个函数中直接返回它,但这样做会错过所有后续调用。

这是导致它的代码:

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);
}
}
}

到目前为止,我有这个解决方案,但它可以改进吗?

您的解决方案很好。如果您想要更紧凑的代码,可以使用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;
}

相关内容

最新更新