Неизменный набор в .NET - PullRequest
6 голосов
/ 09 ноября 2010

.NET BCL имеет неизменяемый тип Set? Я программирую на функциональном диалекте C # и хотел бы сделать что-то вроде

new Set.UnionWith(A).UnionWith(B).UnionWith(C)

Но лучшее, что я могу найти, это HashSet.UnionWith, для которого потребуется следующая последовательность вызовов:

HashSet composite = new HashSet();
composite.UnionWith(A);
composite.UnionWith(B);
composite.UnionWith(C);

Это использование в значительной степени непрозрачно, что затрудняет оптимизацию и понимание. Есть ли лучший способ сделать это без написания пользовательского типа набора функций?

Ответы [ 3 ]

10 голосов
/ 02 августа 2013

Новые неизменные коллекции имеют:

  • ImmutableStack<T>
  • ImmutableQueue<T>
  • ImmutableList<T>
  • ImmutableHashSet<T>
  • ImmutableSortedSet<T>
  • ImmutableDictionary<K, V>
  • ImmutableSortedDictionary<K, V>

Подробнее здесь

Об объединении, которое проходит этот тест:

[Test]
public void UnionTest()
{
    var a = ImmutableHashSet.Create("A");
    var b = ImmutableHashSet.Create("B");
    var c = ImmutableHashSet.Create("C");
    var d = a.Union(b).Union(c);
    Assert.IsTrue(ImmutableHashSet.Create("A", "B", "C").SetEquals(d));
}
5 голосов
/ 09 ноября 2010

Обновление

Этот ответ был написан некоторое время назад, и с тех пор в пространство имен System.Collections.Immutable был добавлен набор неизменяемых коллекций.

Оригинальный ответ

Вы можете использовать свой собственный метод для этого:

public static class HashSetExtensions {
  public static HashSet<T> Union<T>(this HashSet<T> self, HashSet<T> other) { 
    var set = new HashSet<T>(self); // don't change the original set
    set.UnionWith(other);
    return set;
  }
}

Используйте его так:

var composite = A.Union(B).Union(C);

Вы также можете использовать LINQ Union, но чтобы получить набор, вам нужно передать результат конструктору HashSet:

var composite = new HashSet<string>(A.Union(B).Union(C));

Но, HashSet сам изменчив.Вы можете попробовать использовать F # неизменный набор .

Также, как упоминалось в комментариях ErikE , использование Concat дает тот же результат и, вероятно, работает лучше:

var composite = new HashSet<string>(A.Concat(B).Concat(C));
0 голосов
/ 09 ноября 2010

Существует ReadOnlyCollection , но это не хеш-таблица. LINQ добавляет метод Union в качестве расширения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...