Предполагая, что вы имеете в виду LINQ to Objects, он в основном сохраняет набор всех результатов, которые он возвратил до сих пор, и возвращает «текущий» элемент, только если он не был получен ранее.Таким образом, результаты в исходном порядке, с удалением дубликатов.Примерно так (кроме проверки ошибок и т. Д.):
public static IEnumerable<T> Distinct<T>(this IEnumerable<T> source)
{
HashSet<T> set = new HashSet<T>();
foreach (T item in source)
{
if (set.Add(item))
{
// New item, so yield it
yield return item;
}
}
}
Это не гарантировано - но я не могу представить себе более разумной реализации.Это позволяет Distinct()
быть настолько ленивым, насколько это возможно - данные возвращаются как можно скорее, и буферизуется только минимальный объем данных.
Полагаться на это было бы плохой идеей, номожет быть полезно знать, как работает текущая реализация (по-видимому).В частности, вы можете легко заметить, что он начинает , возвращая данные до исчерпания исходной последовательности, просто создавая источник, который регистрирует, когда он генерирует данные, которые будут использоваться Distinct
, а также регистрирует, когда вы получить данные от Distinct
.