How to convert linq results to HashSet or HashedSet
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, looking for the last part of this:
ISet<T> foo = new HashedSet<T>();
foo = (from x in bar.Items select x).SOMETHING;
Could also do this:
HashSet<T> foo = new HashSet<T>();
foo = (from x in bar.Items select x).SOMETHING;
Solution 1:
I don't think there's anything built in which does this... but it's really easy to write an extension method:
public static class Extensions
{
public static HashSet<T> ToHashSet<T>(
this IEnumerable<T> source,
IEqualityComparer<T> comparer = null)
{
return new HashSet<T>(source, comparer);
}
}
Note that you really do want an extension method (or at least a generic method of some form) here, because you may not be able to express the type of T
explicitly:
var query = from i in Enumerable.Range(0, 10)
select new { i, j = i + 1 };
var resultSet = query.ToHashSet();
You can't do that with an explicit call to the HashSet<T>
constructor. We're relying on type inference for generic methods to do it for us.
Now you could choose to name it ToSet
and return ISet<T>
- but I'd stick with ToHashSet
and the concrete type. This is consistent with the standard LINQ operators (ToDictionary
, ToList
) and allows for future expansion (e.g. ToSortedSet
). You may also want to provide an overload specifying the comparison to use.
Solution 2:
Just pass your IEnumerable into the constructor for HashSet.
HashSet<T> foo = new HashSet<T>(from x in bar.Items select x);
Solution 3:
This functionality has been added as an extension method on IEnumerable<TSource>
to .NET Framework 4.7.2 and .NET Core 2.0. It is consequently also available on .NET 5 and later.
ToHashSet<TSource>(IEnumerable<TSource>)
ToHashSet<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)