Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

(Note: This sample code requires C# 7.2 or later, and the Nuget System.Memory package.)

Let's suppose we have a readonly struct as follows:

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

    public int Value { get; }
}

Now let's put it into an array:

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

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

So far so good. You cannot write code to modify array[0].Value directly.

Now suppose we do this:

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

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

So now we've modified the Value component of the readonly struct in the array.

Is this behaviour correct?

like image 495
Matthew Watson Avatar asked Dec 12 '17 15:12

Matthew Watson


1 Answers

Is this behaviour correct?

Yes. A readonly struct does not change the mutability of the variable which holds a copy of the struct! Array elements are variables and variables can vary.

You don't need to use C# 7.2 to see this. Integers are immutable; there's no way to turn the integer 3 into the integer 4. Rather, you replace the contents of a variable containing 3 with 4. The fact that integers are immutable doesn't make variables into constants. Same here. The struct is immutable, just like an int, but the variable holding it is mutable.

Similarly, a readonly field on a struct is a lie; that field can be observed to change because structs do not own their storage. See Does using public readonly fields for immutable structs work? for more on this.

(And of course everything is mutable if you break the rules of the language and runtime by using reflection at a high trust level or unsafe code.)

like image 183
Eric Lippert Avatar answered Sep 25 '22 22:09

Eric Lippert