Suponiendo que se refiere a LINQ to Objects, básicamente mantiene un conjunto de todos los resultados que ha devuelto hasta el momento, y solo cede el elemento "actual" si no se ha producido antes. Entonces, los resultados están en el orden original, con duplicados eliminados. Algo como esto (excepto con la comprobación de errores, etc):
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;
}
}
}
Esto no está garantizado - pero no puedo imaginar una aplicación más sensata. Esto permite que Distinct()
sea tan vago como sea posible: los datos se devuelven tan pronto como sea posible y solo se almacena en el búfer la cantidad mínima de datos.
Confiar en esto sería una mala idea, pero puede resultar instructivo saber cómo funciona la implementación actual (al parecer). En particular, puede observar fácilmente que comienza devolviendo datos antes de agotar la secuencia original, simplemente creando una fuente que inicia sesión cuando produce datos para ser consumidos por Distinct
, y también inicia sesión cuando recibe datos de Distinct
.
También puede agregar su propio método de extensión (por ejemplo, DistinctOrdered) con la implementación que Jon proporcionó. De esta forma, siempre tendrá una implementación con un orden definido independientemente de la versión de .NET Framework. –
Karsten
añadiendo a [Datos de Jon Skeet] (http://meta.stackexchange.com/questions/9134/jon-skeet-facts) - El [.NET Reference Source] (https://referencesource.microsoft.com/# System.Core/System/Linq/Enumerable.cs, 4ab583c7d8e84d6d) se basa en las respuestas de Jon Skeet – Slai