C#如何检测循环引用?

时间:2017-04-07 10:05:51

标签: c#

对于TreeList的一个给定实例,我如何检查要添加到第一个TreeList的另一个TreeList实例是否包含对第一个TreeList本身的(可能是间接的)引用(这将创建一个循环参考)?

例如:

TreeList T1 = new TreeList();
TreeList T2 = new TreeList();
TreeList T3 = new TreeList();
T1.add(T2);
T2.add(T3);
T3.add(T1);

因为当我通过这个实施时,我会陷入循环,因为在T3之后我会回到T1。那么如何检查订单中是否已包含一个。

class TreeList
{
    public string Name { get; set; }
    List<TreeList> items = new List<TreeList>();
    public ReadOnlyCollection<TreeList> Items
    {
        get { return items.AsReadOnly(); }
    }

    public TreeList(string Name)
    {
        this.Name = Name;
    }

    public void Add(string item)
    {
        items.Add(new TreeList(item));
    }
    public void Add(TreeList subTree)
    {
        items.Add(subTree);
    }
    public override string  ToString()
    {
        return Name;
    }
}

2 个答案:

答案 0 :(得分:2)

我认为这些方法可行:

public bool ContainsRecursively(TreeList node)
{
    foreach (TreeList child in items)
        if (child == node || child.ContainsRecursively(node))
            return true;

    return false;
}
public void Add(TreeList tree)
{
    if (this == tree) return; // this tree is 'tree', don't add ourselves!
    if (this.ContainsRecursively(tree)) return; // 'tree' is already in this tree
    if (tree.ContainsRecursively(this)) return; // this tree is already in 'tree'
    items.add(tree);
}

答案 1 :(得分:0)

尝试这种经过深思熟虑的方法:

static void Main(string[] args)
{
    TreeList T1 = new TreeList("");
    TreeList T2 = new TreeList("");
    TreeList T3 = new TreeList("");

    T1.Add(T2);
    T2.Add(T3);

    bool result = Contains(T1, T2); // test 1- true
    bool result2 = Contains(T2, T1); // test 2 - false
    bool result3 = Contains(T3, T2); // test 3 - false
}

public static bool Contains(TreeList source, TreeList searchedElement)
{
     if (source.Equals(searchedElement) || source.Items.Contains(searchedElement))
         return true;

     foreach (TreeList tList in source.Items)
     {
         if (tList.Items.Count > 0 && Contains(tList, searchedElement))
             return true;
     }

     return false;
 }