Может быть, я упускаю детали здесь, но я ожидаю, что IEnumerable.Except () будет работать с Enumerables, не приведенными конкретно к коллекции.
Позвольте мне объяснить на простом примере: у меня есть список файлов в каталоге, и я хочу исключить файлы, начинающиеся с определенной строки.
var allfiles = Directory.GetFiles(@"C:\test\").Select(f => new FileInfo(f));
Получение как совпадающих, так и не совпадающих файлов - это вопрос идентификации одной из двух коллекций, а затем .Except () - в полном списке, верно?
var matching = allfiles.Where(f => f.Name.StartsWith("TOKEN"));
и
var notmatching = allfiles.Except(matching, new FileComparer());
Где FileComparer () - это некоторый класс, который сравнивает полный путь двух файлов.
Что ж, , если я не приведу обе из трех коллекций к списку, последняя переменная не совпадает с полным списком файлов после I .Except () в соответствующей коллекции . Чтобы было ясно:
var allfiles = Directory.GetFiles(@"C:\test\").Select(f => new FileInfo(f));
var matching = allfiles.Where(f => f.Name.StartsWith("TOKEN"));
var notmatching = allfiles.Except(matching, new FileComparer());
не исключает, а
var allfiles = Directory.GetFiles(@"C:\test\").Select(f => new FileInfo(f)).ToList();
var matching = allfiles.Where(f => f.Name.StartsWith("TOKEN")).ToList();
var notmatching = allfiles.Except(matching, new FileComparer()).ToList();
на самом деле делает то, что говорит на банке.
Что мне здесь не хватает? Я не могу понять, почему LINQ не манипулирует коллекцией, которая в данный момент не приведена к списку.
Например, FileComparer даже не вызывается в первом случае.
internal class FileComparer : IEqualityComparer<FileInfo>
{
public bool Equals(FileInfo x, FileInfo y)
{
return x == null ? y == null : (x.Name.Equals(y.Name, StringComparison.OrdinalIgnoreCase) && x.Length == y.Length);
}
public int GetHashCode(FileInfo obj)
{
return obj.GetHashCode();
}
}