生成不可变的循环数据结构
假设我有这个简单的类:
public class Pair {
public readonly object first;
public readonly object second;
public Pair(object first, object second) {
this.first = first;
this.second = second;
}
}
不可能生成成对的循环图。
您将如何创建一个类似的类,它仍然是不可变的,但可以以某种方式用于生成循环图?
Suppose I have this simple class:
public class Pair {
public readonly object first;
public readonly object second;
public Pair(object first, object second) {
this.first = first;
this.second = second;
}
}
It would be impossible to generate a cyclic graph of pairs.
How would you create a similar class, that is still immutable, but can be used somehow to generate cyclic graphs?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
表示图结构的方法有无数种。一种这样的方法是使用矩阵。每行和每列都由顶点索引,矩阵中的每个单元代表一条有向(可能是加权)边。一个简单的循环图,其中 0 没有连接边,1 有连接边,就像这样:
与许多不可变结构一样,构造它们的方式是根据给定矩阵的所需关系返回新结构。例如,如果我们想采用上面的图并将第一个顶点上的边添加回其自身,则表示该图的矩阵就是正义的。
并将其与其他矩阵结合起来,我们只需将它们加在一起即可。
当然,表示矩阵的方法有很多种,对速度、空间和某些其他操作有不同的权衡,但这是另一个问题了。
There are zillions of ways to represent graph structures. One such way is with a matrix. each row and column is indexed by the vertex, and each cell in the matrix represents a directed (possibly weighted) edge. A simple, cyclic graph, with 0's as no connecting edge and 1 with a connecting edge would just be like so:
As with many immutable structures, the way you construct them is by returning new structures based on the desired relationship of given matrices. for instance, if we wanted to take the above graph and add an edge on the first vertex back onto itself, the matrix representing that is just.
and to combine that with the other matrix, we just add them together.
Of course, there are many ways to represent matrices, with different tradeoffs for speed, space, and certain other operations, but that's a different question.
我认为对于您提出的类型的严格不可变类来说这是不可能的。我唯一能想到的就是添加一个带有设置器的属性,该设置器检查字段是否为空,如果为空则允许对其进行设置。通过这种方式,您可以将第一个对象中的
first
字段保留为null
,并且在创建循环中的最后一个对象后,适当地设置该字段以关闭循环。一旦设置,它就不再为空,并且设置器将不再允许更改它。当然,该字段仍然可以通过类内部的代码进行更改,但从外部来看它基本上是不可变的。像这样(C#):
I don't think this is possible with a strictly immutable class of the type you proposed. The only thing I can think of is to add a property with a setter that check whether or not a field is null, and allows it to be set if it is. In this way you could leave the
first
field in the first objectnull
, and once you've created the last object in the cycle set that field appropriately to close the loop. Once it's set, it is no longer null, and the setter would no longer allow it to be changed. It would still be possible for the field to be changed by code internal to the class, of course, but it would be essentially immutable from the outside.Something like this (C#):
我会采用函数式方法,将延续传递给 ctor。或者,它可以采用一系列相似的元素(将 IEnumerable 视为参数)。
I would take a functional approach, passing a continuation into the ctor. Alternately, it could take a sequence of similar elements instead (think IEnumerable as an argument).