是否使用FullName
解决您的问题?
var onlyIn1 = dir1Files.Except(dir2Files).Select(x => new { x.FullName });
或者你可以在Select
语句内把一个自定义字符串:
// get strings in the format "file.ext, c:\path\to\file"
var onlyIn1 = dir1Files.Except(dir2Files).Select(x =>
string.Format("{0}, {1}", x.Name, x.Directory.FullName));
为了能够使用中的对象信息,不创建匿名类型,在有限的信息第一个步骤,而是保持满FileInfo
对象:
var dir1Files = dir1.GetFiles("*", SearchOption.AllDirectories);
var dir2Files = dir2.GetFiles("*", SearchOption.AllDirectories);
更新
代码示例中的实际问题是Except
将使用默认相等比较器进行比较。对于大多数类型(当然在匿名类型的情况下),这意味着它会比较对象引用。由于您有两个与FileInfo
对象的列表,因此Except
将返回第一个列表中的所有对象,其中在第二个列表中找不到相同的对象实例。由于第二个列表中没有第一个列表中的对象实例也存在,因此将返回第一个列表中的所有对象。
为了解决这个问题(并且仍然可以访问要存储的数据),您需要使用Except
overload that accepts an IEqualityComparer<T>
。首先,让我们创建IEqualityComparer
:
class FileInfoComparer : IEqualityComparer<FileInfo>
{
public bool Equals(FileInfo x, FileInfo y)
{
// if x and y are the same instance, or both are null, they are equal
if (object.ReferenceEquals(x,y))
{
return true;
}
// if one is null, they are not equal
if (x==null || y == null)
{
return false;
}
// compare Length and Name
return x.Length == y.Length &&
x.Name.Equals(y.Name, StringComparison.OrdinalIgnoreCase);
}
public int GetHashCode(FileInfo obj)
{
return obj.Name.GetHashCode()^obj.Length.GetHashCode();
}
}
现在你可以使用比较器对文件中的目录比较:
var dir1 = new DirectoryInfo(@"c:\temp\a");
var dir2 = new DirectoryInfo(@"c:\temp\b");
var dir1Files = dir1.GetFiles("*", SearchOption.AllDirectories);
var dir2Files = dir2.GetFiles("*", SearchOption.AllDirectories);
var onlyIn1 = dir1Files
.Except(dir2Files, new FileInfoComparer())
.Select(x => string.Format("{0}, {1}", x.Name, x.Directory.FullName));
所有目录名是相同的,为什么你需要让他们在LINQ查询结果?只需从dir1中取出。 – 2010-12-08 13:00:36