.NET 中的不可变集

发布于 2024-10-01 09:32:11 字数 395 浏览 4 评论 0原文

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

此使用是高度引用不透明的,使得优化和理解变得困难。有没有更好的方法可以在不编写自定义函数集类型的情况下执行此操作?

Does the .NET BCL have an immutable Set type? I'm programming in a functional dialect of C# and would like to do something like

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

But the best I can find is HashSet.UnionWith, which would require the following sequence of calls:

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

This use is highly referentially opaque, making it hard to optimize and understand. Is there a better way to do this without writing a custom functional set type?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云胡 2024-10-08 09:32:11

新的 ImmutableCollections 具有:

  • ImmutableStack
  • ImmutableQueue;
  • ImmutableList
  • ImmutableHashSet
  • ImmutableSortedSet
  • ImmutableDictionary >
  • ImmutableSortedDictionary

更多信息 此处

关于此测试通过的联合:

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

The new ImmutableCollections have:

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

More info here

About the union this test passes:

[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));
}
彻夜缠绵 2024-10-08 09:32:11

更新

这个答案是前一段时间写的,从那时起,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));

Update

This answer was written some time ago, and since then a set of immutable collections have been introduced in the System.Collections.Immutable namespace.

Original answer

You can roll out your own method for this:

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

Use it like this:

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

You can also use LINQ's Union, but to get a set, you'll need to pass the result to the HashSet constructor:

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

But, HashSet itself is mutable. You could try to use F#'s immutable set.

Also, as mentioned in the comments by ErikE, using Concat yields the same result and probably performs better:

var composite = new HashSet<string>(A.Concat(B).Concat(C));
独留℉清风醉 2024-10-08 09:32:11

有一个 ReadOnlyCollection,但它不是哈希表。 LINQ 添加 Union 方法作为扩展。

There is a ReadOnlyCollection, but it's not a hash table. LINQ adds the Union method as an extension.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文