如何将linq结果转换为HashSet或HashedSet

我有一个属于ISet的类。 我试图得到一个linq查询的结果到该属性,但无法弄清楚如何做到这一点。

基本上,寻找这个的最后部分:

ISet<T> foo = new HashedSet<T>(); foo = (from x in bar.Items select x).SOMETHING; 

也可以这样做:

 HashSet<T> foo = new HashSet<T>(); foo = (from x in bar.Items select x).SOMETHING; 

编辑:这是我最终做的:

 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()); } 

我不认为这里有什么内置的东西,但是写一个扩展方法真的很简单:

 public static class Extensions { public static HashSet<T> ToHashSet<T>( this IEnumerable<T> source, IEqualityComparer<T> comparer = null) { return new HashSet<T>(source, comparer); } } 

请注意,您确实需要扩展方法(或者至less是某种forms的generics方法),因为您可能无法明确地表示T的types:

 var query = from i in Enumerable.Range(0, 10) select new { i, j = i + 1 }; var resultSet = query.ToHashSet(); 

您不能通过显式调用HashSet<T>构造函数来完成此操作。 我们依靠generics方法的types推断来为我们做。

现在你可以select命名ToSet并返回ISet<T> – 但是我会坚持使用ToHashSet和具体的types。 这与标准的LINQ操作符( ToDictionaryToList )是一致的,并允许将来的扩展(例如ToSortedSet )。 您可能还想提供一个指定要使用的比较的重载。

只需将您的IEnumerable传递给HashSet的构造函数。

 HashSet<T> foo = new HashSet<T>(from x in bar.Items select x); 

正如@Joel所说的,你可以将你的enumerable传递进去。如果你想做一个扩展方法,你可以这样做:

 public static HashSet<T> ToHashSet<T>(this IEnumerable<T> items) { return new HashSet<T>(items); } 

如果你只需要只读访问权限,而源码是你的方法的一个参数,那么我会去

 public static ISet<T> EnsureSet<T>(this IEnumerable<T> source) { ISet<T> result = source as ISet<T>; if (result != null) return result; return new HashSet<T>(source); } 

原因是用户可能已经用ISet调用了你的方法,所以你不需要创build副本。

这很简单:)

 var foo = new HashSet<T>(from x in bar.Items select x); 

是的T是由OP指定的types:)

您可以使用IEnumerable HashSet构造函数。

 HashSet<T> foo = new HashSet<T>((from x in bar.Items select x).ToArray()); 

Jon的回答是完美的。 唯一需要注意的是,使用NHibernate的HashedSet,我需要将结果转换为集合。 有没有一个最佳的方式来做到这一点?

 ISet<string> bla = new HashedSet<string>((from b in strings select b).ToArray()); 

要么

 ISet<string> bla = new HashedSet<string>((from b in strings select b).ToList()); 

还是我错过了别的?

将IEnumerable简单转换为HashSet,而不是将另一个对象的属性转换为HashSet。 你可以这样写:

 var set = myObject.Select(o => o.Name).ToHashSet(); 

但是,我的select是使用select器:

 var set = myObject.ToHashSet(o => o.Name); 

他们做同样的事情,而第二个显然更短,但我觉得这个习语更适合我的大脑(我认为它就像ToDictionary)。

这是使用扩展方法,支持自定义比较器作为奖励。

 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); }