2014-09-24 97 views
1

收藏我有一類名爲文件夾,它看起來像比較的集合

public class Folder 
{ 
    public int Id{get;set;} 
    public string Titel{get;set;} 
    public List<Folder> Folders{get;set;} 
    public List<Document> Documents{get;set;} 
} 

我從數據庫中獲取的文件夾列表每10秒。現在我需要比較新的文件夾列表和我已經在內存中的文件夾。

這樣做的最好方法是什麼?

我的第一種方法是做:

if(currentFolders.GetHashCode() != newFolders.GetHashCode()) 
{ 
    // Work with changed data 
} 

此外,如果這兩個集合是相同的,我得到不同的散列碼。

我的第二次嘗試是將類標記爲[Serializable]和兩個列表序列化爲Byte[]

byte[] b1, b2; 

    using (var m1 = new MemoryStream()) 
    { 
     using (var m2 = new MemoryStream()) 
     { 
      var binaryFormatter = new BinaryFormatter(); 
      binaryFormatter.Serialize(m1, newFolders); 
      b1 = m1.ToArray(); 

      binaryFormatter.Serialize(m2, currentFolders); 
      b2 = m2.ToArray(); 
     } 
    } 

不幸的是,Folder - class通過LINQ2SQL自動生成的,所以我不能輕易將其標記爲Serializable

我還能做什麼來比較這兩個集合?

+0

實現'IEquatable '或創建' IEqualityComparer '哪裏'T'是'文件夾' – 2014-09-24 14:14:28

回答

0

我自己用的問題解決了:

internal class FolderComparer 
{ 
    internal bool AreCollectionsEqual(IEnumerable<Folder> folderList1, IEnumerable<Folder> folderList2) 
    { 
     var flatFolderList1 = BuildFlatFolderList(folderList1); 
     var flatFolderList2 = BuildFlatFolderList(folderList2); 
     return !flatFolderList1.Except(flatFolderList2).Any(); 
    } 


    private IEnumerable<int> BuildFlatFolderList(IEnumerable<Folder> folders) 
    { 
     List<int> folderIdList = new List<int>(); 
     DoBuildFlatFolderList(folders, folderIdList); 
     return folderIdList; 
    } 

    private void DoBuildFlatFolderList(IEnumerable<Folder> folders, ICollection<int> resultList) 
    { 
     foreach (var folder in folders) 
     { 
      resultList.Add(folder.Id); 
      DoBuildFlatFolderList(folder.Folders.ToList(), resultList); 
     }  
    } 
} 
1

提供:

  • 您的文檔類有一個名稱屬性
  • 您的收藏不包含空值實例
  • 的比較應該在平等的情況下,否則爲false
返回true

您可以執行以下操作:

public bool Compare(Document expected, Document actual) 
{ 
    return (actual.Name == expected.Name); 
} 

public bool Compare(Folder expected, Folder actual) 
{ 
    return (actual.Id == expected.Id) && 
     (actual.Titel == expected.Titel) && 
     Compare(actual.Documents, expected.Documents, Compare) && 
     Compare(actual.Folders, expected.Folders, Compare); 
} 

public bool Compare<T>(ICollection<T> expected, ICollection<T> actual, 
         Func<T, T, bool> comparer) 
{ 
    return (actual.Count == expected.Count) && 
      actual.Zip(expected, (left, right) => comparer(left, right)). 
      All(comparison => comparison); 
} 

可以使用以下方法:

List<Folder> previous = ... 
List<Folder> current = /* Get from DB */ 
if (!Compare(previous, current)) 
{ 
    // Something changed 
} 

您還可以實現IEqualityComparer實現

+0

我沒有得到您的解決方案工作,但我已經自己解決了它 – Tomtom 2014-09-25 07:00:41