在许多情况下,代码将收到IEnumerable<T>
并希望保留其中包含的项目序列。一种常见的方法是在其上调用ToList
。如果有问题的实现已经是一个不可变列表,那么在它上面调用ToList
将是浪费。
如果我只在我的代码中传递集合,我可以定义使用一个扩展方法,它将IEnumerable<T>
传递给Supercat.ImmutableList<T>
的构造函数(实现Supercat.IImmutableList<out T>
),除非提供的对象已经实现Supercat.IImmutableList<T>
(在这种情况下,它将简单地按原样返回)。实现这样的课程并不难。但我担心的是,如果我自己实现这样一个类,并且每个需要这样一个类的人都这样做,每次在使用不同“不可变列表”类的人编写的代码之间传递一个对象时,它就会结束防御性地复制(进入以前的不可变副本的创建者不再认为是不可变的形式)。
因此,我很好奇:是否有任何方法可以实现任何接近刑事质量的方法,以获取一系列项目的不可变快照,使得订阅该方法的所有对象都能够识别彼此的快照作为不可变列表?例如,如果许多人将其不可变类包含一个具有某个特定名称的函数,该函数不会用于任何其他目的,而是指示不变性,那么使代码与使用相同方法的其他人的代码高效地互操作将相当容易(使用静态泛型类和Reflection)。我可以想象很多可能的方法,但我不知道任何接近临界质量的东西。我更喜欢可以从源代码构建的公共领域,即使这需要使用Reflection,但是有兴趣了解那里的任何方法。
答案 0 :(得分:0)
如果“不可变”是指您不希望原始数据的使用者能够更改值,则可以使用ReadOnlyCollection
。但是,在这种情况下,基础列表仍然是可变的,因此消费者无法保证不会在其他地方更改它。
如果您正在寻找真正不可变的集合,最好的选择可能是使用为F#创建的集合。 See this answer.