I have a property on a class that is an ISet. I\'m trying to get the results of a linq query into that property, but can\'t figure out how to do so.
Basically, look
There is an extension method build in the .NET framework and in .NET core for converting an IEnumerable
to a HashSet
: https://docs.microsoft.com/en-us/dotnet/api/?term=ToHashSet
public static System.Collections.Generic.HashSet<TSource> ToHashSet<TSource> (this System.Collections.Generic.IEnumerable<TSource> source);
It appears that I cannot use it in .NET standard libraries yet (at the time of writing). So then I use this extension method:
[Obsolete("In the .NET framework and in NET core this method is available, " +
"however can't use it in .NET standard yet. When it's added, please remove this method")]
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source, IEqualityComparer<T> comparer = null) => new HashSet<T>(source, comparer);
That's pretty simple :)
var foo = new HashSet<T>(from x in bar.Items select x);
and yes T is the type specified by OP :)
As @Joel stated, you can just pass your enumerable in. If you want to do an extension method, you can do:
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> items)
{
return new HashSet<T>(items);
}
Jon's answer is perfect. The only caveat is that, using NHibernate's HashedSet, I need to convert the results to a collection. Is there an optimal way to do this?
ISet<string> bla = new HashedSet<string>((from b in strings select b).ToArray());
or
ISet<string> bla = new HashedSet<string>((from b in strings select b).ToList());
Or am I missing something else?
Edit: This is what I ended up doing:
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source)
{
return new HashSet<T>(source);
}
public static HashedSet<T> ToHashedSet<T>(this IEnumerable<T> source)
{
return new HashedSet<T>(source.ToHashSet());
}
Rather than the simple conversion of IEnumerable to a HashSet, it is often convenient to convert a property of another object into a HashSet. You could write this as:
var set = myObject.Select(o => o.Name).ToHashSet();
but, my preference would be to use selectors:
var set = myObject.ToHashSet(o => o.Name);
They do the same thing, and the the second is obviously shorter, but I find the idiom fits my brains better (I think of it as being like ToDictionary).
Here's the extension method to use, with support for custom comparers as a bonus.
public static HashSet<TKey> ToHashSet<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> selector,
IEqualityComparer<TKey> comparer = null)
{
return new HashSet<TKey>(source.Select(selector), comparer);
}
This functionality has been added as an extension method on IEnumerable<TSource>
to .NET Framework 4.7.2: