Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const, readonly and mutable value types

Tags:

I'm continuing my study of C# and the language specification and Here goes another behavior that I don't quite understand:

The C# Language Specification clearly states the following in section 10.4:

The type specified in a constant declaration must be sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, an enum-type, or a reference-type.

It also states in section 4.1.4 the following:

Through const declarations it is possible to declare constants of the simple types (§10.4). It is not possible to have constants of other struct types, but a similar effect is provided by static readonly fields.

Ok, so a similar effect can be gained by using static readonly. Reading this I went and tried the following code:

static void Main() {     OffsetPoints();     Console.Write("Hit a key to exit...");     Console.ReadKey(); }  static Point staticPoint = new Point(0, 0); static readonly Point staticReadOnlyPoint = new Point(0, 0);  public static void OffsetPoints() {     PrintOutPoints();     staticPoint.Offset(1, 1);     staticReadOnlyPoint.Offset(1, 1);     Console.WriteLine("Offsetting...");     Console.WriteLine();     PrintOutPoints(); }  static void PrintOutPoints() {     Console.WriteLine("Static Point: X={0};Y={1}", staticPoint.X, staticPoint.Y);     Console.WriteLine("Static readonly Point: X={0};Y={1}", staticReadOnlyPoint.X, staticReadOnlyPoint.Y);     Console.WriteLine(); } 

The output of this code is:

Static Point: X=0;Y=0

Static readonly Point: X=0;Y=0

Offsetting...

Static Point: X=1;Y=1

Static readonly Point: X=0;Y=0

Hit a key to exit...

I really expected the compiler to give me some kind of warning about mutating a static readonly field or failing that, to mutate the field as it would with a reference type.

I know mutable value types are evil (why did Microsoft ever implement Point as mutable is a mystery) but shouldn't the compiler warn you in some way that you are trying to mutate a static readonly value type? Or at least warn you that your Offset() method will not have the "desired" side effects?

like image 576
InBetween Avatar asked Jan 24 '12 09:01

InBetween


People also ask

What is difference between const and readonly?

The first, const, is initialized during compile-time and the latter, readonly, initialized is by the latest run-time. The second difference is that readonly can only be initialized at the class-level. Another important difference is that const variables can be referenced through "ClassName.

What is readonly and constant?

readonly keyword is used to define a variable which can be assigned once after declaration either during declaration or in constructor. const keyword is used to define a constant to be used in the program.

What is difference between constant readonly and static?

Constant and ReadOnly keyword is used to make a field constant which value cannot be modified. The static keyword is used to make members static that can be shared by all the class objects.

Why would you use readonly vs const in C #?

A const is a compile-time constant whereas readonly allows a value to be calculated at run-time and set in the constructor or field initializer. So, a 'const' is always constant but 'readonly' is read-only once it is assigned.


1 Answers

Eric Lippert explains what's going on here:

...if the field is readonly and the reference occurs outside an instance constructor of the class in which the field is declared, then the result is a value, namely the value of the field I in the object referenced by E.

The important word here is that the result is the value of the field, not the variable associated with the field. Readonly fields are not variables outside of the constructor. (The initializer here is considered to be inside the constructor; see my earlier post on that subject.)

Oh and just to stress on the evilness of mutable structs, here is his conclusion:

This is yet another reason why mutable value types are evil. Try to always make value types immutable.

like image 105
vc 74 Avatar answered Sep 21 '22 13:09

vc 74