遍历对象图并返回访问节点的递归yield方法
本文关键字:递归 yield 方法 节点 访问 对象图 返回 遍历 | 更新日期: 2023-09-27 18:21:18
我正在尝试编写一个扩展方法,该方法应该遍历对象图并返回所有访问的对象。
我不确定我的方法是否是最好的,所以请对此发表评论。产量也在炒我的大脑。。。我相信答案是显而易见的:/
型号
public class MyClass
{
public MyClass Parent {get;set;}
}
方法
public static IEnumerable<T> SelectNested<T>
(this T source, Func<T, T> selector)
where T : class
{
yield return source;
var parent = selector(source);
if (parent == null)
yield break;
yield return SelectNestedParents(parent, selector).FirstOrDefault();
}
用法
var list = myObject.SelectNested(x => x.Parent);
问题
它几乎起作用了。但它只访问2个对象。它是自己和父母。
因此给出了从c
开始的图c -> b -> a
。返回了c, b
,这不是我想要的。
我正在寻找的结果是b, c
在SelectNested
的最后一行中,您只返回第一个父级:
yield return SelectNestedParents(parent, selector).FirstOrDefault();
您必须返回所有家长:
foreach (var p in SelectNestedParents(parent, selector))
return p;
不使用递归,您可以使用迭代,这可能更有效:
public static IEnumerable<T> SelectNested<T>(this T source, Func<T, T> selector)
where T : class {
var current = source;
while (current != null) {
yield return current;
current = selector(current);
}
}
以下代码应按预期工作:
public static IEnumerable<T> SelectNested<T>()
{
if (source != null){
yield return source;
var parent = selector(source);
// Result of the recursive call is IEnumerable<T>
// so you need to iterate over it and return its content.
foreach (var parent in (SelectNested(selector(source))))
{
yield return parent;
}
}
}
严格来说,您的类看起来是一个列表,而不是一个图,因为selector
只返回一个对象,而不是它们的枚举。因此递归是不必要的。
public static IEnumerable<T> SelectNested<T>(this T source, Func<T, T> selector)
where T : class
{
while (source != null)
{
yield return source;
source = selector(source);
}
}