只读结构在数组中时是否应该是不可变的?

Are readonly structs supposed to be immutable when in an array?

(注意:此示例代码需要 C# 7.2 或更高版本,以及 Nuget System.Memory 程序包。)

假设我们有一个 readonly struct 如下:

public readonly struct Test
{
    public Test(int value)
    {
        Value = value;
    }

    public int Value { get; }
}

现在我们把它放到一个数组中:

var array = new Test[] { new Test(1) };

Console.WriteLine(array[0].Value); // Prints 1

到目前为止一切顺利。您不能编写代码直接修改 array[0].Value

现在假设我们这样做:

array.AsSpan().AsBytes()[3] = 1;

Console.WriteLine(array[0].Value); // Prints 16777217

所以现在我们已经修改了数组中只读结构的 Value 组件。

这种行为是否正确?

Is this behaviour correct?

是的。只读结构不会改变保存该结构副本的变量的可变性!数组元素是变量,变量可以变化。

您无需使用 C# 7.2 即可查看此内容。整数是不可变的;没有办法将整数 3 转换为整数 4。相反,您 将包含 3 的变量的内容替换为 4。整数是不可变的这一事实并不能使变量成为常量。同样在这里。该结构是不可变的,就像一个 int,但持有它的变量是可变的。

同样,结构上的只读字段是一个谎言;可以观察到该字段发生变化,因为 结构不拥有它们的存储空间 。有关详细信息,请参阅 Does using public readonly fields for immutable structs work?

(当然,如果您通过使用高信任级别的反射或不安全的代码来打破语言和运行时的规则,一切都是可变的。)