Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在递归调用中跟踪父级_C#_Recursion_Parent Child - Fatal编程技术网

C# 在递归调用中跟踪父级

C# 在递归调用中跟踪父级,c#,recursion,parent-child,C#,Recursion,Parent Child,我试图在递归调用中跟踪父对象,并标记正确出现的父子关系 有4个类(不介意名称,这是dummycode的一个示例): 根 儿童街区 终于 一次性儿童 所有3个ChildClass都继承自一个抽象类:Child 显然,Root是包含所有子类的顶级类,Root没有父类。但是,在某种程度上,其他类也不例外。根有子,每个子都有子;但并非如此。ChildBlock(以及所有其他)没有存储父级,只有子级列表。见代码: internal abstract class Child { public str

我试图在递归调用中跟踪父对象,并标记正确出现的父子关系

有4个类(不介意名称,这是dummycode的一个示例):

  • 儿童街区
  • 终于
  • 一次性儿童
  • 所有3个ChildClass都继承自一个抽象类:Child

    显然,Root是包含所有子类的顶级类,Root没有父类。但是,在某种程度上,其他类也不例外。根有子,每个子都有子;但并非如此。ChildBlock(以及所有其他)没有存储父级,只有子级列表。见代码:

    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);
        }
    }