public static IEnumerable<UIElement> Traverse(this UIElementCollection source)
{
source.OfType<Grid>().SelectMany(v => Traverse(v.Children));
//This is the top level.
foreach (UIElement item in source)
{
yield return item;
}
}
这永远不会递归返回任何内容。我一直在房子周围。 Linq链应该回调函数/扩展方法,但永远不会。就我所知,这条线无能为力!
答案 0 :(得分:2)
您没有对表达式的结果做任何事情,并且可能不会强制执行延迟评估。如果你真的想忽略表达式的结果,至少尝试在最后添加ToArray();)这应该强制执行评估并递归调用你的Traverse函数。
Bojan解决方案的优势(假设您真正想要的是因为它返回的结果与初始结果不同),实际评估职责是转移到Traverse方法的客户端。因为在你的情况下这些都是内存中的查询,它并没有那么大的区别,但如果这些是数据库查询,那么将ToArray放在某处会有更显着的性能损失(实际数据库查询的数量)。
答案 1 :(得分:2)
永远不会执行递归调用,因为您从不使用SelectMany
的结果。
您可以使此方法变得懒惰,并让客户在需要时对其进行评估
将SelectMany
的结果与当前来源相结合。也许这样的事情可以完成工作(未经测试):
public static IEnumerable<UIElement> Traverse(this UIElementCollection source)
{
var recursive_result = source.OfType<Grid>().SelectMany(v => Traverse(v.Children));
return recursive_result.Concat( source.Cast<UIElement>() );
}
答案 2 :(得分:0)
public static IEnumerable<UIElement> Traverse(this UIElementCollection source)
{
//This is the top level.
foreach (UIElement item in source.OfType<Grid>().SelectMany(v => Traverse(v.Children)).Concat(source.Cast<UIElement>()))
{
yield return item;
}
}
这有所期望的结果,但不确定它是否是最佳的!