L'utilisation de FullName
résout-elle votre problème?
var onlyIn1 = dir1Files.Except(dir2Files).Select(x => new { x.FullName });
Sinon, vous pouvez mettre en place une chaîne personnalisée dans l'instruction 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));
Afin de pouvoir utiliser ces informations dans les objets, ne créent pas des types anonymes avec des informations limitées dans les premiers pas, mais plutôt garder les objets FileInfo
plein:
var dir1Files = dir1.GetFiles("*", SearchOption.AllDirectories);
var dir2Files = dir2.GetFiles("*", SearchOption.AllDirectories);
Mise à jour
Le véritable problème dans votre exemple de code est que Except
sera comparé à l'aide du comparateur d'égalité par défaut. Pour la plupart des types (et certainement dans le cas des types anonymes) cela signifie qu'il va comparer les références d'objets. Puisque vous avez deux listes avec des objets FileInfo
, Except
renverra tous les objets de la première liste, où les mêmes instances d'objet sont introuvables dans la seconde. Comme aucune des instances d'objet de la première liste n'est présente dans la seconde, tous les objets de la première liste seront retournés.
Afin de résoudre ce problème (et avoir toujours accès aux données que vous souhaitez stocker), vous devrez utiliser le Except
overload that accepts an IEqualityComparer<T>
. Tout d'abord, nous allons créer le 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();
}
}
Maintenant, vous pouvez utiliser ce comparateur pour comparer les fichiers dans les répertoires:
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));
Tous les noms de répertoire seront les mêmes, pourquoi avez-vous besoin de les garder à le résultat de la requête LINQ? Juste le prendre de dir1. –