0

我有一个DataStructure类,我希望它是不可变的。

通常,我只是确保我的所有成员都被定义为readonly- 工作完成。但是其中一个成员是一个列表(整数),所以我需要确保List不能修改;所以我将其更改为ReadOnlyCollection<T>. 美好的。

我还需要以某种方式对该集合进行排序 - 再次很好,我在通过.AsReadOnly().

到目前为止,一切都很好。

但最后一步是我想要 3 个不同的构造函数——每个构造函数都接受不同格式的原始数据。现在我必须在每个构造函数中复制将列表转换为必要格式的代码。

如果我将它共同化为一个setList()方法,那么变量不能是readonly,因为它是在非构造方法中分配的。现在我失去了一些不变性。

理想情况下,我可以通过某种方式声明该setList方法只能从构造函数调用,因此允许编辑readonly成员,但我认为不存在。

我可以在吸气剂等中创建包装所有内容,以便该类从外部是不可变的,但我更希望它从内部也是不可变的(特别是考虑到我可以实现这一点,我牺牲了 DRYness)

有没有人对我忘记的语言功能有任何聪明的想法可以解决这个问题?

4

2 回答 2

2

而不是使用void SetList(List)从构造函数调用的,你可以有一个List PrepareList(List). 此方法将准备列表,并将其返回给调用者 - 即:构造函数。

所以代码不会重复 - 除了_list = PrepareList(list)每个构造函数中的做作。

于 2014-07-06T14:30:28.317 回答
0

You can keep it as a normal list inside your class, but only expose it as readonly to the outside (just return .AsReadOnly() in a property).

Though if you definetely want the internal immutability, constructors can call each other:

public Foo( int a ) { ... }
public Foo( string a ) : this( int.Parse( a ) ) { ... }

So you can have most of the code in one constructor (even a private one if needed), and have the converting done in the others. Edit: it is a bit difficult to do alot of work that way, so I still think you should move the conversion out into methods. If the method doesn't access any class members, it'd still be internally immutable.

Another pattern I personally prefer (even if it's just syntactically different) is:

private Foo( int a ) { ... }

public static Foo FromBar( Bar b )
{
    int x;
    // convert from Bar here
    return new Foo( x );
}

public static Foo FromSomethingElse( SomeThingElse b )
{
    int x;
    // convert from SomeThingElse here
    return new Foo( x );
}
于 2014-07-06T14:22:52.107 回答