Как преобразовать результаты 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;
186
задан Cerbrus 16 August 2018 в 22:35
поделиться

5 ответов

Я не думаю, что есть что-то встроенное, что делает это... но очень легко написать метод расширения:

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

Обратите внимание, что здесь вам действительно нужен метод расширения (или, по крайней мере, общий метод какой-то формы), потому что вы можете не иметь возможности выразить тип T явно:

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

Вы не можете сделать это с помощью явного вызова конструктора HashSet. Мы полагаемся на вывод типов для общих методов, чтобы сделать это за нас.

Теперь вы могли бы назвать его ToSet и вернуть ISet - но я бы придерживался ToHashSet и конкретного типа. Это соответствует стандартным операторам LINQ (ToDictionary, ToList) и позволяет расширить их в будущем (например, ToSortedSet). Вы также можете предусмотреть перегрузку, указывающую используемое сравнение.

297
ответ дан 23 November 2019 в 05:49
поделиться

Ответ Джона идеален. Единственное предостережение: с помощью 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()); 

Или мне не хватает чего-то еще?


Изменить: Это то, чем я закончил:

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());
}
1
ответ дан 23 November 2019 в 05:49
поделиться

Как заявил @Joel, вы можете просто передать свой перечисляемый объект. Если вы хотите выполнить метод расширения, вы можете сделать:

public static HashSet<T> ToHashSet<T>(this IEnumerable<T> items)
{
    return new HashSet<T>(items);
}
17
ответ дан 23 November 2019 в 05:49
поделиться

Это довольно просто :)

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

и да, T - это тип, указанный OP:)

2
ответ дан 23 November 2019 в 05:49
поделиться

Просто передайте свой IEnumerable в конструктор для HashSet.

HashSet<T> foo = new HashSet<T>(from x in bar.Items select x);
73
ответ дан 23 November 2019 в 05:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: