我有当前的功能:
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);
}
}
}
}
它:
- 分析注册表项的所有子项
- 对于每个子键,解析其所有值
- 如果值是字符串,则将其添加到迭代器
我担心的是每个循环都嵌入了两个,我一点也不喜欢。我想把这个函数一分为二。
问题是,我最终得到的返回类型是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;
}