2016-03-28 97 views
0

我收集了一个DataItem类。找到一个集合中的循环依赖关系c#

的DataItem:PropertyRefItem店REF到DataItem可能是同一个集合。

public class DataItem 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public DataItem RefItem { get; set; } 
} 

收藏:

private List<DataItem> dataitems; 

    public List<DataItem> DataItems 
    { 
     get { return dataitems; } 
     set { dataitems = value; } 
    } 

现在我有一个在收集集合中添加数据和验证数据的两种方法。

public void AddItem(DataItem item) 
    { 
     DataItems.Add(item); 
    } 

    public bool ValidateDataItems() 
    { 
     //Logic for circular reference 
     // 
     return true; 
    } 

我想要一个验证方法中的算法来检查我的collection中是否有任何循环依赖。以下是我的无效数据。由于item3再次由item1指向。

 var item1 = new DataItem() {ID=1,Name="First Item",RefItem =null}; 
     var item2 = new DataItem() { ID = 1, Name = "First Item", RefItem = item1 }; 
     var item3 = new DataItem() { ID = 1, Name = "First Item", RefItem = item2 }; 
     item1.RefItem = item3; 
     AddItem(item1); 
     AddItem(item2); 
     AddItem(item3); 

如果项目被添加到集合像Item1-> ITEM2,item2->项目3,item3-> ITEM1或其中一类的ref项指向后面的任何其他可能的组合。我想验证方法返回false。

这是一个循环依赖问题,但我找不到任何具体的算法在c#中这样做。

+1

你不能遍历所有引用,跟踪现有引用?如果你已经遇到了一个新的参考,它是循环的。 –

回答

3

尝试是这样的solution

public class DataItem 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public DataItem RefItem { get; set; } 
}  

public class Checker 
{ 
    public static bool Check(DataItem item) 
    { 
     var chain = new Dictionary<DataItem, DataItem>(); 
     chain.Add(item, null); 
     try 
     { 
      ProcessNodes(chain, item); 
      return true; 
     } 
     catch (ArgumentException) 
     { 
      return false; 
     } 
    } 

    private static void ProcessNodes(Dictionary<DataItem, DataItem> chain, DataItem item) 
    { 
     if (item.RefItem != null) 
     {     
      chain.Add(item.RefItem, null); 
      ProcessNodes(chain, item.RefItem); 
     } 
    } 

    public static bool ValidateDataItems(List<DataItem> items) 
    { 
     foreach(var item in items) 
      if(!Check(item)) 
       return false; 
     return true;     
    } 
} 

public static void Main() 
{ 
    var item1 = new DataItem() { ID = 1, Name = "First Item", RefItem = null }; 
    var item2 = new DataItem() { ID = 1, Name = "First Item", RefItem = item1 }; 
    var item3 = new DataItem() { ID = 1, Name = "First Item", RefItem = item2 }; 
    item1.RefItem = item3; 

    Console.WriteLine(Checker.Check(item1)); 
    item1.RefItem = null; 
    Console.WriteLine(Checker.Check(item1)); 

    //Sample how to check all existing items  
    Console.WriteLine(Checker.ValidateDataItems(new List<DataItem>{item1, item2, item3}) ? "items is OK" : "One or more items have dependency");   
} 
+0

感谢您的回答。但是我不能限制用户在集合中添加项目,如果发生上述情况,我只需要显示一些验证消息。觉得它已经有一个集合,现在我只需要验证它。 –

+0

另外,如果在项目列表中没有通过ref连接,那么我将不得不再次调用Check方法。由于编译时我无法做出决定,所以我只需要为每个项目调用它。 –

+0

@KyloRen然后,而不是抛出异常把你的验证信息。通常情况下最好不要破坏集合,然后花时间在事实之后检查它。 – kenny