我有一个名为Folder的类,看起来像
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 :(得分: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实施
答案 1 :(得分: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);
}
}
}