C# 遍历对象图并返回访问节点的递归屈服方法
我正在尝试编写一个扩展方法,它应该遍历一个对象图并返回所有访问过的对象 我不确定我的方法是否是最好的,所以请对此发表评论。我的大脑也在煎熬。。。我相信答案是显而易见的:/ 型号C# 遍历对象图并返回访问节点的递归屈服方法,c#,recursion,extension-methods,yield-return,C#,Recursion,Extension Methods,Yield Return,我正在尝试编写一个扩展方法,它应该遍历一个对象图并返回所有访问过的对象 我不确定我的方法是否是最好的,所以请对此发表评论。我的大脑也在煎熬。。。我相信答案是显而易见的:/ 型号 public class MyClass { public MyClass Parent {get;set;} } 方法 public static IEnumerable<T> SelectNested<T> (this T source, Func<T, T> s
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();
}
问题
它几乎起作用了。但它只访问2个对象。这是我自己和父母
因此,给定这个图,从c
开始,从c
开始<代码>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);
}
}
公共静态IEnumerable SelectNested(此T源,函数选择器)
T:在哪里上课{
无功电流=电源;
while(当前!=null){
产生回流电流;
电流=选择器(电流);
}
}
在选择嵌套的最后一行中,您只返回第一个父项:
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);
}
}
公共静态IEnumerable SelectNested(此T源,函数选择器)
T:在哪里上课{
无功电流=电源;
while(当前!=null){
产生回流电流;
电流=选择器(电流);
}
}
以下代码应按预期工作:
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;
}
}
}
public静态IEnumerable SelectNested()
{
如果(源!=null){
收益回报源;
var parent=选择器(源);
//递归调用的结果是IEnumerable
//因此,您需要对其进行迭代并返回其内容。
foreach(在(SelectNested(selector(source)))中的var父对象)
{
收益母公司;
}
}
}
以下代码应按预期工作:
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;
}
}
}
public静态IEnumerable SelectNested()
{
如果(源!=null){
收益回报源;
var parent=选择器(源);
//递归调用的结果是IEnumerable
//因此,您需要对其进行迭代并返回其内容。
foreach(在(SelectNested(selector(source)))中的var父对象)
{
收益母公司;
}
}
}
严格来说,您的类看起来是一个列表,而不是一个图形,因为选择器
只返回一个对象,而不是它们的枚举。因此,递归是不必要的
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);
}
}
公共静态IEnumerable SelectNested(此T源,函数选择器)
T:在哪里上课
{
while(源!=null)
{
收益回报源;
源=选择器(源);
}
}
严格来说,您的类看起来是一个列表,而不是一个图形,因为选择器
只返回一个对象,而不是它们的枚举。因此,递归是不必要的
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);
}
}
公共静态IEnumerable SelectNested(此T源,函数选择器)
T:在哪里上课
{
while(源!=null)
{
收益回报源;
源=选择器(源);
}
}
我喜欢非递归方法。但它应该是var current=选择器(源)代码>来满足我的需要。谢谢你的帮助@Snæbjørn在您最初的帖子中,您的方法总是返回未经修改的源代码。这里提供的代码做同样的事情。通过将current
初始化为source
,它消除了yield return source
行,从而简化了代码。这是正确的。然而,产生返回源的唯一原因是因为它是一个递归函数。我真正看到的结果是没有初始对象。正如我在文章最后一行试图解释的:)我喜欢非递归方法。但它应该是var current=选择器(源)代码>来满足我的需要。谢谢你的帮助@Snæbjørn在您最初的帖子中,您的方法总是返回未经修改的源代码。这里提供的代码做同样的事情。通过将current
初始化为source
,它消除了yield return source
行,从而简化了代码。这是正确的。然而,产生返回源的唯一原因是因为它是一个递归函数。我真正看到的结果是没有初始对象。正如我试图在帖子的最后一行解释的那样:)