生成不可变循环数据结构

时间:2010-10-24 03:37:50

标签: data-structures immutability lazy-evaluation cyclic-graph

假设我有这个简单的类:

public class Pair {
    public readonly object first;
    public readonly object second;

    public Pair(object first, object second) {
        this.first = first;
        this.second = second;
    }
}

生成对的循环图是不可能的。

你将如何创建一个类似的类,它仍然是不可变的,但可以某种方式用于生成循环图?

3 个答案:

答案 0 :(得分:3)

有数以万种的方式来表示图形结构。一种方法是使用矩阵。每个行和列由顶点索引,并且矩阵中的每个单元表示有向(可能是加权的)边。一个简单的循环图,0表示没有连接边,1表示连接边,就像这样:

| 0 1 |
| 1 0 |

与许多不可变结构一样,构造它们的方式是基于给定矩阵的期望关系返回新结构。例如,如果我们想要获取上面的图并在第一个顶点上添加一条边回到自身上,那么代表它的矩阵就是。

| 1 0 |
| 0 0 |

并将其与其他矩阵相结合,我们只需将它们加在一起。

| 0 1 |  +  | 1 0 |  ==  | 1 1 |
| 1 0 |     | 0 0 |      | 1 0 |

当然,有很多方法来表示矩阵,对速度,空间和某些其他操作有不同的权衡,但这是一个不同的问题。

答案 1 :(得分:0)

我认为这不可能使用你提出的类型的严格不可变类。我唯一能想到的是添加一个带有setter的属性来检查一个字段是否为null,并允许它被设置为是否为null。通过这种方式,您可以将first字段保留在第一个对象null中,并且一旦您在循环中创建了最后一个对象,就可以适当地关闭循环。一旦设置,它就不再为空,并且setter将不再允许它被更改。当然,仍然可以通过类内部的代码来改变字段,但它本质上是不可改变的。

像这样(C#):

public class Pair {
    private object first;
    private object second;

    public Pair(object first, object second) {
        this.first = first;
        this.second = second;
    }

    public object First {
        get { return first; }
        set 
        {
            if (first == null)
            {
                first = value;
            }
        }
    }

    // and a similar property for second
}

答案 2 :(得分:0)

我会采取功能性方法,将延续传递给ctor。或者,它可能需要一系列相似的元素(将IEnumerable视为参数)。