【发布时间】:2011-03-10 15:54:37
【问题描述】:
如何使用 LINQ 使ComponentTraversal.GetDescendants() 变得更好?
问题
public static class ComponentTraversal
{
public static IEnumerable<Component> GetDescendants(this Composite composite)
{
//How can I do this better using LINQ?
IList<Component> descendants = new Component[]{};
foreach(var child in composite.Children)
{
descendants.Add(child);
if(child is Composite)
{
descendants.AddRange((child as Composite).GetDescendants());
}
}
return descendants;
}
}
public class Component
{
public string Name { get; set; }
}
public class Composite: Component
{
public IEnumerable<Component> Children { get; set; }
}
public class Leaf: Component
{
public object Value { get; set; }
}
回答
我编辑了 Chris 的答案以提供我添加到我的公共库中的通用扩展方法。我可以看到这对其他人也有帮助,所以这里是:
public static IEnumerable<T> GetDescendants<T>(this T component, Func<T,bool> isComposite, Func<T,IEnumerable<T>> getCompositeChildren)
{
var children = getCompositeChildren(component);
return children
.Where(isComposite)
.SelectMany(x => x.GetDescendants(isComposite, getCompositeChildren))
.Concat(children);
}
谢谢克里斯!
还有,
请查看 LukeH 在http://blogs.msdn.com/b/wesdyer/archive/2007/03/23/all-about-iterators.aspx 的回答。他的回答总体上提供了解决此问题的更好方法,但我没有选择它,因为它不是我问题的直接答案。
【问题讨论】:
-
如果它现在可以工作,你为什么要改变它?仅仅因为 Linq 看起来更漂亮?还是您希望获得性能提升?我个人不会因为这些原因而改变工作方法,因此“更好”是非常主观的。
-
@Bazzz,在每个子组合中,我都会实例化一个新数组。我希望有一种更具成本效益的方式,而且 LINQ 可能是有道理的。我也可能想针对 IQueryable 做这种事情,在这种情况下 LINQ 肯定会带来性能优势。然而,我想知道如何在 LINQ 中做到这一点的最大原因是我还没有弄清楚。
标签: c# linq .net-3.5 linq-to-objects composite