Reputation: 14060
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;
Upvotes: 7
Views: 5203
Reputation: 5927
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);
}
Upvotes: 2
Reputation: 1503090
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.)
Upvotes: 20
Reputation: 3257
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
Upvotes: 1