【发布时间】:2009-04-09 07:44:03
【问题描述】:
我需要编写一个树搜索方法,它接受一个类型参数 T 并返回树中存在的所有类型 T 的项目。有没有办法做到这一点?在这一点上,我更喜欢优雅而不是效率......
【问题讨论】:
我需要编写一个树搜索方法,它接受一个类型参数 T 并返回树中存在的所有类型 T 的项目。有没有办法做到这一点?在这一点上,我更喜欢优雅而不是效率......
【问题讨论】:
类似这样的:
internal static IEnumerable<T> AllDescendantNodes<T>( this TreeNode input )
where T class;
{
T current = null;
foreach ( TreeNode node in input.Nodes )
if( (current = node as T) != null )
{
yield return current;
foreach ( var subnode in node.AllDescendantNodes<T>() )
yield return subnode;
}
}
然后您可以将其作为扩展方法针对根节点调用:
foreach( MyCustomNodeClass item in rootNode.AllDescendantNodes<MyCustomNodeClass>() )
{
...
}
【讨论】:
嗯,在内部,该方法必须遍历树的所有元素,因此跳过仅枚举它,并使用 OfType LINQ 方法并没有那么远:
var onlyTs = yourTree.OfType<SomeT>();
【讨论】:
假设你的树是通用的。即Item<T>。
int count = yourTree.Count(p => p == typeof(T));
否则,解析每个节点并比较“item == typeof(T)”
【讨论】:
您需要的是一个基本的树遍历函数(前序、中序或后序——这无关紧要)和一个过滤器函数。然后你可以将这两者组合在一起,得到你需要的东西:
IEnumerable<T> Traverse(Tree<T> tree)
{
yield return tree.Data;
foreach(Tree<T> subtree in tree.Subtrees)
foreach(T t in Traverse(subtree))
yield return t;
}
IEnumerable<U> Filter<T, U>(IEnumerable<T> source)
where U : T
{
foreach(T t in source)
if(t is U)
yield return (U)t;
}
【讨论】:
t as U 并且检查 null 比 if( t is U ) (U) t 更快;