class string
是不可变的。不可能实现不可变的结构类型,因为您无法禁用或覆盖赋值操作(=)。即使您定义了只读结构体,也始终可以使用赋值运算符来更改结构体类型的值。例如,x,y
是只读结构体的值。 x = y;
会改变x
的内容。因此,C#语言参考中的readonly struct部分是不正确的。这是正确的吗?
不,你错了。
readonly struct
上的文档完全正确。您的问题包含损坏的链接,此文档页面和部分的正确 URL 是 this。
解释非常简单。考虑这个例子:
readonly struct A {
internal A(int first, string second) { First = first; Second = second; }
internal readonly int First { get; init; }
internal readonly string Second { get; init; }
}
static void ReadonlyTest() {
A a = new(1, "constant value");
//a.A = 12; will fail to compile
}
static class ReadonlyUsage {
static A value = new(0, "original value");
internal static void Demo() {
A a = new(1, "constant value");
//a.First = 12; // will fail to compile
a = new(2, "another value");
// this is mutable:
value = new(3, "one more value");
//value.First = 13; // will fail to compile
// still mutable:
value = new(4, "How much longer?!");
}
}
这里什么是可变的?除了
ReadonlyUsage.value
之外什么都没有,它使得 ReadonlyUsage
也可变。它与 struct A
无关——它是不可变的。完全一样System.String
。
让我们看看:分配给
A a
怎么样?此赋值是否会使 ReadonlyUsage
可变?不会。您将新值(struct A
是值类型)分配给堆栈变量。它仅存在于堆栈中,并且在当前堆栈帧退出后将被删除。堆栈不属于类,它属于调用ReadonlyUsage.Demo
的线程。如果它是 实例类,则该赋值不会修改
Demo
类中的任何内容。我们只需创建一个新的 struct A
实例,并且从不修改任何已经存在的实例,这就是它被称为不可变的原因。
现在,给
ReadonlyUsage.value
的分配怎么样?这是可能的,因为 ReadonlyUsage
是可变的。同样,我们创建 struct A
的新实例,并且永远不会修改任何已存在的实例。
如何防止分配给
ReadonlyUsage.value
?简单:也做到readonly
:
static readonly A value = new(0, "original value");
就是这样。我希望误会能够消除。那么你会接受这个答案吗?如果没有,请进一步提问。