7

In C# 3.0 you can assign null to int? type (in CLR int? is a struct):

int? a = null;

but when you define a custom struct:

struct MyStruct
{

}

there's an error during the compilation of this code:

MyStruct a = null;

The error is as follows:

Cannot convert null to 'Example.MyStruct' because it is a non-nullable value type

While int? is a struct in CLR it is somehow counterintuitive that we can assign null to it. I suppose that null is implicitly casted or boxed to a certian int? value that represents the null value. How is it done precisely? How can I extend MyStruct in such a way that it would be possible to execute the line:

MyStruct a = null;
0

3 Answers 3

20

It's because int? is actually shorthand Nullable<int>. You can do the same thing for your type too:

MyStruct? a = null;

null can only be implicitly converted to a nullable type, which means any reference type or any nullable value type - where the latter means Nullable<T> for some T.

Note that this ability to conver from null is really a language feature - the compiler is converting this:

int? a = null;

into

int? a = new int?();

They mean the same thing - basically a "null" value for a nullable value type is a value where HasValue is false, which it will be by default. It's not the same as a null reference - although boxing a null value like that will result in a null reference.

(This is one example of a feature which crosses language, library and CLR boundaries. The library part is quite simple, the CLR part is only to do with boxing and unboxing - but there's quite a lot in terms of lifted operators etc in the language.)

Sign up to request clarification or add additional context in comments.

7 Comments

Interesting timing of this question. I just got done reading the chapter about nullable types in Jon's book (C# in Depth) . Every C# developer should read it!! Thanks Jon.
I'd just like to point out that I didn't pay for that comment :)
Your statement "Note that this is really a language feature" is somewhat confusing since the CLR does (as you mention later on) handle Nullable<> structs specially in boxing and unboxing operations, which IMHO makes this a runtime feature (with some ? syntactic sugar to top it off).
@Lucero: The conversion from the null literal is a language feature. I'll edit to make that clearer.
@Jon Skeet: So my problem lies with the language feature that you've mentioned. Is it possible to somehow utilize that language feature to automatically convert MyStruct a = null to MyStruct a = new MyStruct() ?
|
2

Structs are value types in C#, not reference types, so they can't be null.

MyStruct? = null;

will work, but remember that structs are immutable, as a example:

public struct Point 
{
   public int x, y;

   public Point(int p1, int p2) 
   {
       x = p1;
       y = p2;    
   }
}

void Main()
{

    //create a point
    var point1 = new Point(10, 10); 

    //assign point2 to point, point2
    var point2 = point1; 

    //change the value of point2.x
    point2.x = 20; 

    //you will notice that point1.x does not change
    //this is because point2 is set by value, not reference.
    Console.WriteLine(point1.x);
    Console.WriteLine(point2.x);

}

6 Comments

Well MyStruct? is still a value type - but it can be null.
And not all structs are immutable (unfortunately).
@Jon: I thought structs were passed by value, how can they not immutable?
@Master: Just because they're passed by value doesn't make them immutable. See System.Drawing.Point for example - you can create an instance, then set its X and Y properties afterwards.
@Jon: I always thought of point1.x = 1; as being congruent to point1 = new Point(1, point1.y);. Perhaps that's just how I cope though...
|
1

just adding, a nullable type can represent the normal range of values for its underlying value type, plus an additional null value.

In notation, just as int is actually Int32, not any int, the ? sign means a nullable. Nullable, in this case.

http://msdn.microsoft.com/en-us/library/1t3y8s4s%28VS.80%29.aspx

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.