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?
Eric Lippert explains what’s going on here:
Oh and just to stress on the evilness of mutable structs, here is his conclusion: