在C#.NET 4.0中,我正在努力想出最有效的方法来确定2个项目列表的内容是否包含任何差异。
我不需要知道差异是什么,只是根据我的标准,列表是否不同,这是真是假。
我想要比较的2个列表包含FileInfo对象,我想只比较每个项目的FileInfo.Name和FileInfo.LastWriteTimeUtc属性。所有FileInfo项都用于位于同一目录中的文件,因此FileInfo.Name值将是唯一的。
总结一下,我正在寻找以下标准的单个布尔结果:
谢谢,
凯尔
答案 0 :(得分:1)
我会使用自定义IEqualityComparer<FileInfo>
执行此任务:
public class FileNameAndLastWriteTimeUtcComparer : IEqualityComparer<FileInfo>
{
public bool Equals(FileInfo x, FileInfo y)
{
if(Object.ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
return x.FullName.Equals(y.FullName) && x.LastWriteTimeUtc.Equals(y.LastWriteTimeUtc);
}
public int GetHashCode(FileInfo fi)
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = hash * 23 + fi.FullName.GetHashCode();
hash = hash * 23 + fi.LastWriteTimeUtc.GetHashCode();
return hash;
}
}
}
现在,您可以使用HashSet<FileInfo>
与此比较器和HashSet<T>.SetEquals
:
var comparer = new FileNameAndLastWriteTimeUtcComparer();
var uniqueFiles1 = new HashSet<FileInfo>(list1, comparer);
bool anyDifferences = !uniqueFiles1.SetEquals(list2);
请注意,我使用的是FileInfo.FullName
而不是Name
,因为名字根本不具备。
旁注:另一个优点是您可以将此比较器用于许多LINQ方法,例如GroupBy
,Except
,Intersect
或Distinct
。
答案 1 :(得分:0)
这不是最有效的方法(可能在快速和肮脏的类别中排名为5分中的四分之一):
var comparableListA = ListA.Select(a =>
new { Name = a.Name, LastWrite = a.LastWriteTimeUtc, Object = a});
var comparableListB = ListB.Select(b =>
new { Name = b.Name, LastWrite = b.LastWriteTimeUtc, Object = b});
var diffList = comparableListA.Except(comparableListB);
var youHaveDiff = diffList.Any();
<强>解释强>
匿名类通过属性值进行比较,这是您要做的事情,这导致我考虑沿着这些线进行LINQ投影。
<强> P.S。强>
你应该仔细检查语法,我只是在没有编译器的情况下解决这个问题。