我有一个基类:
public abstract class BaseClass{
public bool IsSelected {get; set;}
}
具有表示层次结构的集合的派生类:
public class DerivedOne : BaseClass{
public ObservableCollection<BaseClass> Children {get; set;}
}
另一个派生类:
public class DerivedTwo : BaseClass{
}
查找DerivedOne
根下IsSelected设置为true的所有元素的最简单方法是什么?
答案 0 :(得分:1)
你省略了一些要求细节,但我认为这样的事情应该有效:
public IEnumerable<BaseClass> AllIsSelected(BaseClass root)
{
if (root.IsSelected)
{
yield return root;
}
var composite = root as DerivedOne;
if (composite != null)
{
foreach (var v in composite.Children)
{
foreach (var x in AllIsSelected(v))
{
yield return x;
}
}
}
}
当然,如果您想要一次完整列表,则可以构建列表而不是使用&#39; yield&#39;。
这与此处讨论的设计相同:IEnumerable and Recursion using yield return。
正如另一个答案所说,你可以使用LINQ来缩短它。此版本避免制作临时列表。
public IEnumerable<BaseClass> AllIsSelected(BaseClass root)
{
if (root.IsSelected)
{
yield return root;
}
var composite = root as DerivedOne;
if (composite != null)
{
foreach (var x in composite.Children.SelectMany(v => AllIsSelected(v)))
{
yield return x;
}
}
}
答案 1 :(得分:0)
最简单的方法是使用带递归的LINQ
public IEnumerable<BaseClass> GetAllSelectedChildren(DerivedOne derivedOne)
{
return derivedOne.Children.SelectMany(GetAllSelected);
}
public IEnumerable<BaseClass> GetAllSelected(BaseClass baseClass)
{
var selected = new List<BaseClass>();
if(baseClass.IsSelected)
{
selected.Add(baseClass);
}
var derivedOne = baseClass as DerivedOne;
if(derivedOne != null)
{
selected.AddRange(GetAllSelectedChildren(derivedOne));
}
return selected;
}
答案 2 :(得分:0)
使用简单的Linq
。
return root.Children
.SelectMany(c => new[]{ c }.Concat(c.Children)) // flatten the structure including self node.
.Where(e => e.IsSelected) // filter selected items
.ToList();