我在一个类上有一个属性,它是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;

当前回答

与其简单地将IEnumerable转换为HashSet,还不如将另一个对象的属性转换为HashSet。你可以这样写:

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

但是,我更倾向于使用选择器:

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

其他回答

如果您只需要对集合进行只读访问,并且源是方法的参数,那么我会选择

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调用您的方法,因此您不需要创建副本。

这很简单:)

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

T是OP指定的类型:)

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

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

与其简单地将IEnumerable转换为HashSet,还不如将另一个对象的属性转换为HashSet。你可以这样写:

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

但是,我更倾向于使用选择器:

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

在.NET框架和.NET核心中有一个用于将IEnumerable转换为HashSet的扩展方法:https://learn.microsoft.com/en-us/dotnet/api/?term=ToHashSet

public static System.Collections.Generic.HashSet<TSource> ToHashSet<TSource> (this System.Collections.Generic.IEnumerable<TSource> source);

似乎我还不能在. net标准库中使用它(在撰写本文时)。然后我用这个扩展方法:

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