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

时间:2017-12-12 15:06:53

标签: 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; }
}

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

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

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

这种行为是否正确?

1 个答案:

答案 0 :(得分:17)

  

这种行为是否正确?

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

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

类似地,结构上的只读字段是谎言;可以观察到该字段发生变化,因为结构不拥有其存储。有关详情,请参阅Does using public readonly fields for immutable structs work?

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