2016-03-28 19 views
0

DataItem sınıfından oluşan bir koleksiyonum var.Koleksiyona bir dairesel bağımlılık bulun C#

Dataıtem:PropertyRefItem depolar aynı toplama olabilecek DataItem için ref.

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

Koleksiyonu:

private List<DataItem> dataitems; 

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

Şimdi koleksiyonunda verileri koleksiyonunda veri eklemek ve doğrulamak için iki yöntem vardır.

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

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

benim collection.For eski herhangi döngüsel bağımlılık olup olmadığını kontrol etmek için validate yönteminde bir algoritma istiyorum. Aşağıda benim için geçersiz bir veri var. Item3 tekrar item1 ile işaret edilir. item1 veya bir sınıfın bir ref öğesi tekrar gösterdiği yere başka olası kombinasyon ürün Item1-> Öğe2, item2-> item3, item3- gibi koleksiyona eklenirse

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

>. Yanlışlık döndürmek için doğrulama yöntemi istiyorum.

Bu bir dairesel bağımlılık sorunudur, ancak C# için bunu yapmak için herhangi bir somut algoritma bulamadım.

+1

Eğer mevcut referanslar takip, tüm başvuruları çapraz olamaz mı? Eğer zaten karşılaştığınız yeni bir referans ise, daireseldir. –

cevap

3

bu solution gibi bir şey deneyin:

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

Cevabınız için teşekkürler. Ancak, bir kullanıcının koleksiyonda öğeler eklemesini kısıtlayamıyorum, sadece yukarıdaki gibi bir doğrulama mesajı göstermem gerekecek. Şimdiye kadar bir koleksiyon var gibi düşünün ve şimdi sadece doğrulamak zorundayım. –

+0

Ayrıca, bir öğe listesinde ref ile bağlı değilse, o zaman tekrar kontrol yöntemini tekrar aramak zorundayım. Ve bu kararı derleme zamanından beri yapamayacağımdan, sadece her öğe için onu aramak zorunda kalacağım. –

+0

@KyloRen ardından istisna atmak yerine doğrulama mesajınızı koydu. Genellikle koleksiyonu bozmamak, daha sonra kontrol etmek için zaman harcamak daha iyidir. – kenny

İlgili konular