2014-09-24 3 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 
} 

Кроме того, если обе коллекции идентичны я получаю разные hashcodes.

Моя вторая попытка была пометить класс как [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 '' '' '' Folder' –

ответ

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

Предоставлено:

  • ваш класс Документ имеет одно свойство Имя
  • Ваши коллекции не содержат неопределенные экземпляры
  • ваше сравнение должно вернуться верно в случае равенства и ложь в противном случае

Вы можете сделать следующее:

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

Смежные вопросы