A while back I wrote
a discourse on value type initialization. However, in answering a
question on the Microsoft C# newsgroup I came upon a quite bizarre sitution
introduced in Whidbey (.NET 2.0). Look at the following code:
class App
{
static void Main(string[] args)
{
Point p;
p.X = 10;
}
}
struct Point
{
int x;
public int X
{
get{ return x; }
set{ x = value; }
}
}
This fails compilation with the error "Use of unassigned local variable p". This
is expected as p.X = 10; is actually running a
method under the covers and the C# compiler won't allow you to call any members
of a value type until all of its data members have been explicitly initialized
either by setting them all directly (only possible if they are public) or
getting the compiler to emit an initobj
instruction or run a constructor (see the aforementioned discourse).
Now. there is a Point class
already defined in the Systerm.Drawing namespace
- lets use that one instead.
using System.Drawing;
class App
{
static void Main(string[] args)
{
Point p;
p.X = 10;
}
}
This fails compilation in exactly the same way in .NET 1.x but it
compiles cleanly in Whidbey! So are there special flags on
System.Drawing.Point that make the C# compiler treat it differently
from the custom Point class? Not that I can see
from using Reflector so
either I've missed something, or the compiler is special casing this type (and
at least the System.Drawing.Size which I've
also checked exhibits the same behavior).
I have no problem with teh C# team changing the behavior of the compiler to just
allow the .locals init IL opcode to initialize
a value type and not enforce greater level of stringency - in fact that might
be quite neat. But to have differing behavior for system value types and custom
value types is just bizarre and confusing.