У меня есть свойство в классе, который является 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 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
). Вы также можете предусмотреть перегрузку, указывающую используемое сравнение.
Ответ Джона идеален. Единственное предостережение: с помощью 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());
}
Как заявил @Joel, вы можете просто передать свой перечисляемый объект. Если вы хотите выполнить метод расширения, вы можете сделать:
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> items)
{
return new HashSet<T>(items);
}
Это довольно просто :)
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);