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

Mat*_*son 12 c# immutability c#-7.2 system.memory

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

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

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

    public int Value { get; }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Console.WriteLine(array[0].Value); // Prints 1
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.您无法编写代码来array[0].Value直接修改.

现在假设我们这样做:

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

Console.WriteLine(array[0].Value); // Prints 16777217
Run Code Online (Sandbox Code Playgroud)

所以现在我们已经修改Value了数组中readonly结构的组件.

这种行为是否正确?

Eri*_*ert 17

这种行为是否正确?

是.readonly结构不会改变包含结构副本的变量的可变性!数组元素是变量,变量可以变化.

您不需要使用C#7.2来查看此内容.整数是不可变的; 没有办法将整数3转换为整数4.而是将含有3的变量的内容替换为4.整数是不可变的这一事实并不会将变量变为常量.同样在这里.结构是不可变的,就像一个int,但保存它的变量是可变的.

类似地,结构上的只读字段是谎言; 可以观察到该字段发生变化,因为结构不拥有其存储空间.请参阅对不可变结构使用公共只读字段是否有效?了解更多.

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

  • @PetSerAl:不.将字节直接写入内存是您可以做的最危险的事情之一.如果你不喜欢你这样做会发生什么,那么我的建议是:不要这样做. (3认同)