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
のオブジェクトを持つ2つのリストがあるため、Except
は、最初のリストからすべてのオブジェクトを返します。同じオブジェクトインスタンスが2番目のリストに見つかりません。最初のリストのオブジェクトインスタンスはいずれも2番目のリストに存在しないので、最初のリストのすべてのオブジェクトが返されます。
これを修正するには(まだ保存したいデータにアクセスするため)、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から取る。 –