Leo qiao
Leo qiao

Reputation: 23

It is impossible to implement an immutable struct type

class string is immutable. It is impossible implementing an immutable struct type as you can't disable or override assignment operation (=). Even you define a readonly struct, you can always change the value of the struct type by using assignment operator.

For example, x,y are values of a readonly struct. x = y; will change the content of x. So, the readonly struct section in C# language reference is not correct. Is this right?

Upvotes: -3

Views: 137

Answers (2)

Sergey A Kryukov
Sergey A Kryukov

Reputation: 884

No, you are not right. The documentation on readonly struct is perfectly correct. Your question contains a broken link (you've fixed it in one of your comments, but it's better to modify the question), the correct URL of this documentation page and section is this.

The explanation is pretty simple. Consider this example:

    readonly struct A {
        internal A(int first, string second) { First = first; Second = second; }
        internal readonly int First { get; init; }
        internal readonly string Second { get; init; }
    }

    static class ReadonlyUsage {
        static A value = new(0, "original value");
        internal static void Demo() {
            A a = new(1, "constant value");
            //a.First = 12; // will fail to compile
            a = new(2, "another value");
            // this is mutable:
            value = new(3, "one more value");
            //value.First = 13; // will fail to compile
            // still mutable:
            value = new(4, "How much longer?!");
        }
    }

What is mutable here? Nothing except ReadonlyUsage.value, and it makes ReadonlyUsage also mutable. It has nothing to do with struct A — it is immutable. Exactly as System.String.

Let's see: what about the assignment to A a? Does this assignment make ReadonlyUsage mutable? No. You assign a new value (and struct A is a value type) to a stack variable. It exists only in the stack and will be removed after the exit of a current stack frame. The stack does not belong to the class, it belongs to the thread calling ReadonlyUsage.Demo. The assignment does not modify anything in the Demo class if it was an instance class. We simply create a new struct A instance and never modify any of the already existing instances, that's why it is called immutable.

Now, what about the assignment to ReadonlyUsage.value? It is possible, because ReadonlyUsage is mutable. Again, we create new instances of struct A and never modify any of the already existing instances.

How to prevent the assignment to ReadonlyUsage.value? Easy: make it readonly, too:

static readonly A value = new(0, "original value");

Upvotes: 2

shingo
shingo

Reputation: 27307

I found a section on Wikipedia that may explain your question:

Violating immutability

Immutability does not imply that the object as stored in the computer's memory is unwriteable. Rather, immutability is a compile-time construct that indicates what a programmer can do through the normal interface of the object, not necessarily what they can absolutely do (for instance, by circumventing the type system or violating const correctness in C or C++).

In my own words, "Immutable" and "Assignment" are two independent concepts in C# as a programming language. "Immutable" just refers to the immutability of an object's state. The reason you think value types are mutable by reassignment is because the assignment of value types happens to overwrite the memory they are allocated. As stated on wiki, if there is a way to write the memory referenced by a string, it would also violate its immutability. (and this is really possible)

Upvotes: 1

Related Questions