12

(注意:此示例代码需要 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了数组中只读结构的组件。

这种行为正确吗?

4

1 回答 1

18

这种行为正确吗?

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

您无需使用 C# 7.2 即可看到这一点。整数是不可变的;没有办法将整数 3 转换为整数 4。相反,您将包含 3 的变量的内容替换为 4。整数是不可变的这一事实不会使变量成为常量。同样在这里。struct 是不可变的,就像 int 一样,但保存它的变量是可变的。

同样,结构上的只读字段是谎言;可以观察到该字段发生变化,因为结构不拥有它们的存储。请参阅对不可变结构使用公共只读字段是否有效?了解更多信息。

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

于 2017-12-12T15:21:24.700 回答