问题标签 [immutable-collections]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - 跨 API 传递不可变集合的最佳模式是什么
在不变性之前,IEnumerable是许多 API 中的首选接口,因为它的优点是 API 对传递对象的实际类型不敏感。
当然,这至少有两个缺点:
API 背后的代码不能依赖collectionOfThings的不变性,并且可能会遇到“集合修改”异常或遇到其他其他微妙问题。
我们不知道collectionOfThings是真正的集合还是只是一个延迟查询。如果我们假设它是一个真正的集合,而实际上不是,我们会冒着运行多个枚举而降低性能的风险。如果我们假设它是一个延迟查询并且它实际上是一个真正的集合,那么将其转换为本地列表或其他冻结集合会产生不必要的成本,尽管它确实有助于保护我们免受第一个问题的影响(在执行“ToList”操作时仍然存在竞争条件)。显然,我们可以编写少量代码来检查这一点并尝试做“正确的事情”,但这很烦人。
我必须承认,除了使用命名约定之外,我从来没有找到一个令人满意的模式来解决这个问题。务实的方法似乎是IEnumerable是传递集合的最低摩擦方法,尽管有缺点。
现在,有了不可变集合,情况得到了很大改善......
不再存在集合修改的风险,并且对多次枚举的性能影响没有歧义。
然而,我们显然失去了 API 的灵活性,因为我们现在必须传入一个ImmutableList。如果我们的客户端有其他类型的可枚举不可变集合,则必须将其复制到ImmutableList中才能被使用,即使我们只想枚举它。
理想情况下,我们可以使用类似的界面
但是当然,除非按照惯例,接口不能强制执行诸如不变性之类的语义。
使用基类可能有效
除了创建未密封的不可变类以免子类引入可变性被认为是不好的形式。无论如何,这在 BCL 中还没有完成。
或者我们可以继续在 API 中使用 IEnumerable 并使用命名约定来明确我们的代码依赖于传入的不可变集合。
所以......我的问题是在传递不可变集合时哪些模式被认为是最好的?一旦我们开始使用不可变性, ImmutableList是“新的IEnumerable ”还是有更好的方法?
更新
IReadOnlyCollection(下面的 Yuval Itzchakov 建议)是对IEnumerable的明显改进,但仍不能完全保护消费者免受集合中不受控制的更改。值得注意的是,Roslyn 代码库大量使用了不可变性(主要通过ImmutableArray),并且在将这些传递给其他方法时似乎使用了显式类型,尽管有几个位置ImmutableList被传递到接受IEnumerable的方法中。
java - ImmutableMap 中是否有 with() 方法?
我正在观看视频(https://www.youtube.com/watch?v=ZeO_J2OcHYM),发现我们可以使用 with() 方法初始化 ImmutableMap。见下文:
但是,当我检查 ImmutableMap 的 API 时,我没有找到 with() 方法。该方法已被弃用吗?
c# - ImmutableHashSet .Contains 返回 false
我有一个ImmutableHashSet<ListItem>
基本项目列表(准确地说来自 System.Collections.Immutable)并尝试调用以下代码
但这返回false。
即使以下代码行都返回true
我什至可以编写以下内容并返回 true:
我做错了什么,我想避免写 .OfType 的东西。
编辑:
编辑2:
这是我的问题的可重现代码,看起来像ImmutableHashSet<>
缓存GetHashCode
并且不会将当前GetHashCode
与列表中的条目进行比较,有没有办法告诉ImmutableHashSet<>
项目GetHashCode
可能不同,至少对于我目前正在检查的项目,因为嘿它该死的相同参考...
如果我将代码更改为ImmutableHashSet<>
可以ImmutableList<>
正常工作,那么如果你们没有提出任何好主意,我将切换到列表。
java - JAVA:不可变集作为列表
我目前从函数调用 (getFeatures()) 中返回了一个 ImmutableSet,并且由于我的其余代码的结构将在稍后执行 - 将其更改为 List 会容易得多。我试图强制转换它会产生运行时异常。我还四处寻找将其转换为列表的函数调用,但无济于事。有没有办法做到这一点?我最近的 [失败] 尝试如下所示:
我发现 wrapperSet.asList() 会给我一个 ImmutableList 但是我更喜欢一个可变列表
c# - 我是否必须包含所有 System.Collections.Immutable 依赖项?
我刚刚从(一个较旧的)Microsoft.Bcl.Immutable
NuGet 包切换到System.Collections.Immutable
并惊讶地发现我的项目中的所有这些新包依赖项:
它们被列为 NuGet 包的依赖项,因此它们有权在那里,但它们显然也已经安装在我的 PC 和我的目标环境 (Azure btw) 上,因为它们随框架一起提供。
我的项目中已经有大量的包,如果可能的话,我希望避免这 8 个包造成的额外开销(并且不会让自己陷入困境)。
删除这些依赖项是否安全?
我现在是否必须在整个项目中使用这些包,因为它们可能与其安装的版本不同,并且我的项目的某些部分现在可能使用了错误的包?(由于某些 DLL 链接疯狂?)
编辑:只是为了完整性,因为之前有评论:依赖项是实际的包(不是命名空间)并且必须下载,我的目标是使用 .NET 4.6 进行编译,在 VS2015 中工作。尽管某些东西已经过时并且不必正常加载包,但这完全有可能吗?
c# - ReadonlyCollection,对象是不可变的吗?
我正在尝试使用 ReadOnlyCollection 使对象不可变,我希望对象的属性是不可变的。
但我有点困惑。
我尝试使用 foreach 将对象的属性更改为 MyReadOnlyList 并且...我可以更改 value 属性,是否正确?我了解 ReadOnlyCollection 设置了一个添加级别以使对象不可变。
c# - C# 多维不可变数组
我需要为简单的游戏创建一个字段。在第一个版本中,该字段就像 Point[,]
- 二维数组。
现在我需要使用 System.Collections.Immutable (这是重要的条件)。我试图谷歌并找不到任何东西,这可以帮助我。我不明白如何创建二维 ImmutableArray(或 ImmutableList)?
c# - C#不可变对象setter理解
我有不可变的 F1 类。我想改变它的一个领域。在 set 方法中,我必须返回 F1 类的新实例并进行更改。我不明白我怎么能做到这一点。
String.cs 中有 Replace 方法。String 是 C# 中的不可变类(或者我认为是这样)。替换方法定义如下:
所以我不知道 ReplaceInternal 是如何工作的,然后找不到我的问题的答案。
java - java Guava和Scala之间不可变列表的连接差异
我正在尝试使用 java 的 spark,但我被 java 中的不可变集合卡住了。
正如我在 Scala 中理解的那样,当组合两个不可变列表时,不会发生深拷贝。然而,java 中可用的不可变列表,如番石榴,是防御性副本。(如果我错了请纠正我)
所以我的问题很简单:
- 是否有一些 Java 不可变列表与 scala 不可变列表具有相同的行为?
- 如果第一个问题的答案是否定的,那么在 java 代码中使用 scala 不可变集合的一般(标准)方法是什么?
非常感谢。
c# - System.Collections.Immutable 对 System.Runtime 和 FxCop/metrics 的引用
Windows 7
安装后,我.NET 4.5.2
创建了一个针对 .NET 4.5.2 的新 ClassLibrary 项目。
我想通过启动Visual Studio 2013metrics.exe
附带的FxCop
位于c:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Static Analysis Tools\FxCop\
.
一切正常。
然后我 nuget System.Collections.Immutable v1.1.37
。
我可以在引用中看到只有 System.Collections.Immutable 被引用,因为找到了其他依赖项(System.Runtime
,System.Collections
等System.Diagnotics.Debug
)(我想在c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\Facades\
)
我创建了一个创建虚拟 ImmutableArray 的虚拟方法var foo = new List<int>().ToImmutableArray();
一切都可以编译并且工作得很好。
我重新启动了指标计算。
我有以下错误:
metrics.exe /f:c:\dev\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll /o:toto.xml
错误:CA0055:无法加载文件:'c:\dev\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll'。
如果我对程序集执行相同的命令,System.Immutable.Collections
则会出现以下错误:
计算文件 'c:\dev\ClassLibrary1\ClassLibrary1\bin\Debug\System.Collections.Immutable.dll' 的指标。找不到框架程序集“System.Runtime,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a”。
现在,如果我复制System.Runtime
位于c:\Windows\Microsoft.NET\Framework\v4.0.30319\
输出目录中的文件,计算代码指标就ClassLibrary1.dll
可以正常工作。但是,如果我复制其中的版本c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\Facades\
,如果再次失败。
在 Web 应用程序中使用 Immutable 调试另一个库时,我可以在“加载的模块”中看到以下内容:
System.Runtime.dll C:\windows\Microsoft.Net\assembly\GAC_MSIL\System.Runtime\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Runtime.dll 是 否 跳过加载符号。544 4.06.1055.0 06/11/2015 03:49 000007FED10D0000-000007FED10D9000 [15760] w3wp.exe [4] /LM/W3SVC/2/ROOT/WebSite-2-131026947404276669
所有这一切让我认为 System.Collections.Immutable 使用了 System.Runtime 的版本c:\Windows\Microsoft.NET\Framework\v4.0.30319\
所以我想,“让我们添加一个对该程序集的显式引用。” 如果这样做,我会收到以下编译错误:
错误 CS1703:已导入具有等效标识的多个程序集:“c:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Runtime.dll”和“C:\Program Files (x86)\Reference Assemblies\Microsoft\ Framework.NETFramework\v4.5.2\Facades\System.Runtime.dll'。删除重复引用之一。
某处有问题,我无法确定。
我使用/ignoreinvalidtargets
for解决了这个错误metrics.exe
。
有人知道真正的错误吗?
(我还尝试以 .NET Framework 4 为目标,并c:\Windows\Microsoft.NET\Framework\v4.0.30319\
使用 CopyLocal = true 添加对所有依赖程序集的引用。尽管有以下警告,它仍然有效:
某些 NuGet 包是使用与当前目标框架不同的目标框架安装的,可能需要重新安装。访问http://docs.nuget.org/docs/workflows/reinstalling-packages了解更多信息。受影响的包:System.Collections、System.Collections.Immutable、System.Diagnostics.Debug、System.Globalization、System.Linq、System.Resources.ResourceManager、System.Runtime、System.Runtime.Extensions、System.Threading
)
谢谢。