Я пытаюсь создать метод расширения AddRange для HashSet, чтобы сделать что-то вроде этого:

var list = new List<Item>{ new Item(), new Item(), new Item() };
var hashset = new HashSet<Item>();
hashset.AddRange(list);

Это то, что у меня до сих пор:

public static void AddRange<T>(this ICollection<T> collection, List<T> list)
{
    foreach (var item in list)
    {
        collection.Add(item);
    }
}

Проблема в том, что когда я пытаюсь использовать AddRange, я получаю эту ошибку компилятора:

The type arguments for method 'AddRange<T>(System.Collections.Generic.ICollection<T>, System.Collections.Generic.List<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Другими словами, я должен использовать вместо этого:

hashset.AddRange<Item>(list);

Что я здесь делаю не так?

2
Daniel T. 18 Окт 2009 в 01:13
Странно, я вставил ваши фрагменты кода (вместе с пустым определением для Item) в новый консольный проект, и у меня это работает.
 – 
G-Wiz
18 Окт 2009 в 01:23
4
Это должно работать нормально ... не могли бы вы опубликовать полный код, иллюстрирующий проблему? В качестве примечания: вы должны объявить параметр как IEnumerable<T>, а не List<T>, это даст вам больше гибкости
 – 
Thomas Levesque
18 Окт 2009 в 01:40

2 ответа

Лучший ответ

Ваш код отлично работает для меня:

using System.Collections.Generic;

static class Extensions
{
    public static void AddRange<T>(this ICollection<T> collection, List<T> list)
    {
        foreach (var item in list)
        {
            collection.Add(item);
        }
    }
}

class Item {}

class Test
{
    static void Main()
    {
        var list = new List<Item>{ new Item(), new Item(), new Item() };
        var hashset = new HashSet<Item>();
        hashset.AddRange(list);
    }
}

Не могли бы вы дать аналогичную короткую, но полную программу, которая не компилируется?

3
Jon Skeet 18 Окт 2009 в 01:18
1
Я разобрался в проблеме, но она не связана с методом расширения. Скорее, я пытался неявно преобразовать List в HashSet, что не сработало и привело к тому, что метод расширения также не смог неявно преобразовать его.
 – 
Daniel T.
19 Окт 2009 в 23:17
2
Другие, прежде чем использовать этот принятый ответ в своем коде, просмотрите ответ ниже, используя UnionWith.
 – 
Kevin Kalitowski
24 Янв 2013 в 21:41
Можно ли получить диапазон элементов из хеш-набора при наличии начального индекса и считать, как GetRange () для списков?
 – 
inquisitive
2 Апр 2013 в 09:41
1
@inquisitive: это не имеет никакого логического смысла, поскольку хеш-наборы логически не упорядочены. Вполне возможно, что если вы добавите элемент, порядок всего набора изменится. Вы можете использовать Skip / Take из LINQ, но это предполагает, что вам не следует использовать HashSet для начала.
 – 
Jon Skeet
2 Апр 2013 в 09:44

Использовать

hashSet.UnionWith<Item>(list);
29
gav 23 Фев 2012 в 16:43
Спасибо - я этого не заметил.
 – 
Russell Troywest
31 Авг 2011 в 11:36
UnionWish изменяет HashSet, чтобы он содержал только общие элементы. AddRange должен добавлять элементы ell из конкретной коллекции в HasSet.
 – 
CMircea
18 Дек 2011 в 14:08
6
Нет, это не так. UnionWith имеет то же значение, что и List.AddRange. Кажется, вы смешиваете его с IntersectWith.
 – 
splintor
3 Янв 2012 в 07:52