如果类的只读字段不是不可变的,则它是不可变的
本文关键字:不可变 读字段 如果 | 更新日期: 2023-09-27 17:58:49
如果我有一个只有只读字段的C#类,但字段的类型不是不可变的,那么这个类被认为是不可变的吗?
这个类是不可变的吗?
public class Foo
{
private readonly int[] _blah;
public Foo(int[] blah)
{
_blah = blah;
}
public int[] Blah { get { return _blah; } }
}
_blah不是一成不变的,因为我可以更改数组的成员,尽管数组成员变量永远不会更改。
那么,如果一个类的字段都是只读的,那么它是不可变的吗?或者,只有当它的字段不仅是只读的而且本身也是不可变的,那么一个类是不可变吗?
这将真正取决于你问谁或你的意思。有些人可能会说类本身是不可变的,因为它的直接成员是不可变。有人可能会说,类及其所有成员(及其属性等)——基本上,整个对象图——必须是不可变的,才能被认为是不可变。
- 标记为只读的私有字段数组是不可变的,但这并不意味着不能用不同的值替换索引。解决此问题的方法是返回数组的副本或数组的枚举
- 数组的对象可以是不可变的,也可以不是不可变的。无论你们是让它们不可变,还是返回它们的克隆,或者其他什么,这都取决于你们自己
在您的情况下,对象是整数(不可变),但数组本身不是(同样,取决于您定义的不可变)。如果你只想保证私有字段不能被更改,并且不关心索引,那么你就可以了。但是,如果要锁定索引,则需要以另一种方式公开数组。
此外,ReadOnlyCollection<T>
是一个很好的收藏。它是一个集合,包含对原始集合的引用(它将其包装),因此索引不能更改。
还有,以防万一。。。对于"不可变"的实际含义,你已经有了不同的答案。
此类的实例不是不可变的,因为您可以更改它们的内容。例如foo.Blah[0] = 42;
。但是,如果将Blah
属性更改为IEnumerable<int>
或IReadOnlyList<int>
,则实例将被认为是不可变的。
这个类不是不可变的,因为它可以被继承并添加其他东西。
如果它遵循三个原则,我认为它是不可变的:
- 将字段设为只读字段
- 提供一个公共财产获取加速器
- 如果不再需要继承该类,请将其密封
这些并不是严格定义为不可变的硬性规则。它们只是指导方针。