Tengo una propiedad en una clase que es un ISet. Estoy tratando de obtener los resultados de una consulta linq en esa propiedad, pero no puedo entender cómo hacerlo.
Básicamente, buscando la última parte de esto:
ISet<T> foo = new HashedSet<T>();
foo = (from x in bar.Items select x).SOMETHING;
También podría hacer esto:
HashSet<T> foo = new HashSet<T>();
foo = (from x in bar.Items select x).SOMETHING;

HashedSet. Es confuso desde entoncesC#yLINQno tengo nada llamadoHashedSet.Respuestas:
No creo que haya nada incorporado que haga esto ... pero es realmente fácil escribir un método de extensión:
Tenga en cuenta que realmente desea un método de extensión (o al menos un método genérico de alguna forma) aquí, porque es posible que no pueda expresar el tipo
Texplícitamente:No puede hacer eso con una llamada explícita al
HashSet<T>constructor. Confiamos en la inferencia de tipos para métodos genéricos que lo hagan por nosotros.Ahora podría elegir nombrarlo
ToSety regresarISet<T>, pero me quedaría conToHashSetel tipo concreto. Esto es consistente con los operadores estándar de LINQ (ToDictionary,ToList) y permite una expansión futura (por ejemploToSortedSet). También puede proporcionar una sobrecarga que especifique la comparación a utilizar.fuente
GetHashCodeyEquals? Si no, no van a ser muy buenos en un HashSet ...ForEach, peroToHashSettiene mucho más sentido: no conozco ninguna razón para no hacerToHashSetotra cosa que la normal "no cumple con la barra de utilidad" (con la que no estoy de acuerdo, pero ...)Simplemente pase su IEnumerable al constructor de HashSet.
fuente
bar.Itemsva a serT. Dado lo fácil que es hacer este propósito general y la frecuencia con la que aparecen los tipos anónimos en LINQ, creo que vale la pena dar un paso más.Esta funcionalidad se ha agregado como método de extensión
IEnumerable<TSource>a .NET Framework 4.7.2 :ToHashSet<TSource>(IEnumerable<TSource>)ToHashSet<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)fuente
Como dijo @Joel, puede pasar su enumerable. Si desea hacer un método de extensión, puede hacer:
fuente
Si solo necesita acceso de solo lectura al conjunto y la fuente es un parámetro para su método, entonces iría con
La razón es que los usuarios pueden llamar a su método con el
ISetya no necesita crear la copia.fuente
Hay una compilación de método de extensión en .NET Framework y en .NET core para convertir una
IEnumerableaHashSet: https://docs.microsoft.com/en-us/dotnet/api/?term=ToHashSetParece que todavía no puedo usarlo en las bibliotecas estándar de .NET (en el momento de la escritura). Entonces uso este método de extensión:
fuente
Eso es bastante simple :)
y sí T es el tipo especificado por OP :)
fuente
La respuesta de Jon es perfecta. La única advertencia es que, usando HashedSet de NHibernate, necesito convertir los resultados en una colección. ¿Hay una manera óptima de hacer esto?
o
¿O me estoy perdiendo algo más?
Editar: Esto es lo que terminé haciendo:
fuente
ToListes generalmente más eficiente queToArray. ¿Solo necesita implementarseICollection<T>?En lugar de la simple conversión de IEnumerable a un HashSet, a menudo es conveniente convertir una propiedad de otro objeto en un HashSet. Podrías escribir esto como:
pero, mi preferencia sería usar selectores:
Hacen lo mismo, y el segundo es obviamente más corto, pero creo que el idioma se adapta mejor a mi cerebro (lo considero como ToDictionary).
Este es el método de extensión para usar, con soporte para comparadores personalizados como un bono.
fuente