不可能实现不可变的结构类型

问题描述 投票:0回答:1

class string
是不可变的。不可能实现不可变的结构类型,因为您无法禁用或覆盖赋值操作(=)。即使您定义了只读结构体,也始终可以使用赋值运算符来更改结构体类型的值。例如,
x,y
是只读结构体的值。
x = y;
会改变
x
的内容。因此,C#语言参考中的readonly struct部分是不正确的。这是正确的吗?

c# immutability readonly value-type
1个回答
0
投票

不,你错了。

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");

就是这样。我希望误会能够消除。那么你会接受这个答案吗?如果没有,请进一步提问。

© www.soinside.com 2019 - 2024. All rights reserved.