C# 在递归调用中跟踪父级
我试图在递归调用中跟踪父对象,并标记正确出现的父子关系 有4个类(不介意名称,这是dummycode的一个示例):C# 在递归调用中跟踪父级,c#,recursion,parent-child,C#,Recursion,Parent Child,我试图在递归调用中跟踪父对象,并标记正确出现的父子关系 有4个类(不介意名称,这是dummycode的一个示例): 根 儿童街区 终于 一次性儿童 所有3个ChildClass都继承自一个抽象类:Child 显然,Root是包含所有子类的顶级类,Root没有父类。但是,在某种程度上,其他类也不例外。根有子,每个子都有子;但并非如此。ChildBlock(以及所有其他)没有存储父级,只有子级列表。见代码: internal abstract class Child { public str
internal abstract class Child
{
public string name;
public List<Child> children;
public Child()
{
name = "Child";
children = new List<Child>();
}
public virtual void AddChild(Child child)
{
children.Add(child);
}
}
internal class ChildFinally : Child
{
public ChildFinally(string level)
{
name = level + ": ChildFinally";
children = new List<Child>();
}
}
这种递归调用必须保持这种方式。此外,我不能让孩子们知道他们的父母
我有没有办法追踪ChildDispossible类型的孩子是否有ChildFinally类型的父母(在任何级别)
编辑:如果需要,我可以提供完整的(可复制的)dummycode。根据我们所知道的很难判断,但我想我可以猜一点 无论如何,如果我是对的,你将以某种方式行走你的树,因此我的建议是在你行走你的树时记住一些路径信息(应该是微不足道的-这只是你的步行者的另一个论点)-在那里你可以很容易地存储像最后一个孩子这样的东西 这就是你的例子:
private static void DisplayChildren(Child child)
{
DisplayChildren(child, new []{child});
}
private static void DisplayChildren(Child child, Child[] path)
{
foreach (Child c in child.children)
{
Console.WriteLine(c.name);
var newPath = new List<Child>(path);
newPath.Add(c);
DisplayChildren(c, newPath.ToArray());
}
}
或更简单(如果有,只记得父母):
这个怎么样:
internal abstract class Child
{
public string name;
public List<Child> children;
public Child Parent {get;set;}
public Child()
{
name = "Child";
children = new List<Child>();
}
public virtual void AddChild(Child child)
{
children.Add(child);
child.Parent = this;
}
}
public static class ChildHelpers
{
public static Child[] GetAncestors(this Child self)
{
var path = new List<Child>();
var current = self;
while (current.Parent != null)
{
path.Add(current.Parent);
current = current.Parent;
}
return path.ToArray(); // maybe reverse first...
}
}
我在想一本字典
var parents = new Dictionary<Child, Child>();
void SetParent(Child parent)
{
foreach (Child c in parent.children)
{
parents[c] = parent;
SetParent(c);
}
}
var parents=newdictionary();
void SetParent(子父级)
{
foreach(parent.children中的子c)
{
父母[c]=父母;
SetParent(c);
}
}
您只需使用
SetParent(root)
调用一次,子类是否可以访问任何可以为其提供树的内容?父级设置一个简单的属性来保存“has a parent of this type”这样的值是否足够好/可用?我同意@Lasse,需要另一个了解树的对象,任何子级都可以通过某种方式访问该对象来找到它的lef,并将树拆分为不可能的interogates;这是dummycode。它与具有不同类型代码块的microsoft服务相关,这些代码块不知道它们的父块。我在那里没有影响力;我无法添加属性。可以在单独的对象/类中进行跟踪,还是需要能够对给定的子对象(例如child.hasChildFinallyParent
)调用方法?如果不能让子对象知道其父对象,可以让另一个对象知道子对象->父对象关系,如哈希表。或者你可以通过所有的父母来循环。这正是我不能做的。正如我在问题中所解释的,不可能有父属性。谢谢您的努力。@Matthijs:parent属性不在Child
中,而是在ChildHolder
中。您的第一个选项实际上提供了一个解决方案,其中Childclass获得Parentproperty。。。但是,是的,你的第一个解决方案可能有效,但它只适用于直系父母,而不是所有高于直系父母的父母;这就是我要找的…祖父母==.Parent.Parent!您可以递归地/在循环中使用Parent
属性来创建路径。请参阅我添加的get祖先
扩展方法。这将给你的父母,父母的父母等一个孩子。工程像一个魅力!我没想到这件事会如此琐碎。。哇!非常感谢!很高兴我能提供帮助,但我认为第二个示例也应该有效-它应该记得调用路径中最后一次看到的ChildFinally
。嗯,我想它可能会有效,但我仍然喜欢第一个。我实际上也不需要使用ChildFinally对象,只知道它是否存在就足够了。编辑:它也有用,你很好
private static void DisplayChildren(Child child)
{
DisplayChildren(child, null);
}
private static void DisplayChildren(Child child, ChildFinally lastFinalParent)
{
if (child is ChildFinally)
lastFinalParent = (ChildFinally)child;
foreach (Child c in child.children)
{
Console.WriteLine(c.name);
DisplayChildren(c, lastFinalParent);
}
}
internal abstract class Child
{
public string name;
public List<Child> children;
public Child Parent {get;set;}
public Child()
{
name = "Child";
children = new List<Child>();
}
public virtual void AddChild(Child child)
{
children.Add(child);
child.Parent = this;
}
}
public static class ChildHelpers
{
public static Child[] GetAncestors(this Child self)
{
var path = new List<Child>();
var current = self;
while (current.Parent != null)
{
path.Add(current.Parent);
current = current.Parent;
}
return path.ToArray(); // maybe reverse first...
}
}
internal class ChildHolder
{
public Child TheChild {get; private set;} // get the payload child
public ChildHolder Parent {get;set;} // store information about parent
public ChildHolder(Child child)
{
TheChild = child;
}
public virtual void AddChild(ChildHolder childHolder)
{
TheChild.Add(childHolder.TheChild); // store children in original child object
childHolder.Parent = this; // and pass my parent information to childs holder
}
}
var parents = new Dictionary<Child, Child>();
void SetParent(Child parent)
{
foreach (Child c in parent.children)
{
parents[c] = parent;
SetParent(c);
}
}