views:

511

answers:

3

Possible Duplicate:
C# okay with comparing value types to null

The behaviour described below is specific to .net-3.5 only

Hello,

I just ran across the most astonishing behavior in the C# compiler;

I have the following code:

Guid g1 = Guid.Empty;
bool b1= (g1 == null);

Well, Guid is not nullable therefore it can never be equal to null. The comparison i'm making in line 2 always returns false.

If you make the same thing for an integer, the compiler issues an warning saying the result will always be false:

int x=0;
bool b2= (x==null);

My question is: Why does the compiler lets you compare a Guid to null?
According to my knowledge, it already knows the result is always false.
Is the built-in conversion done in such a way that the compiler does assume null is a possible value?
Am I missing anything here?

Thanks, Luís

+7  A: 

The comparison is valid because the compiler converts the Guid to a Nullable<Guid> and then it makes sense.

There is a bug report on the warning not being issued here.

See here here for a fuller explanation from Eric Lippert.

Mark Byers
+21  A: 

Mark is correct. Value types that define their own equality operators automatically get lifted-to-nullable versions defined as well, for free. The nullable equality operator that takes two nullable guids is applicable in this situation, will be called, and will always return false.

In C# 2, this produced a warning, but for some reason, this stopped producing a warning for guid-to-null but continues to produce a warning for int-to-null. I don't know why; I haven't had time to investigate yet.

I apologize for the error; I probably screwed up one of the warning-detection code paths when rewriting the nullable logic in C# 3. The addition of expression trees to the language majorly changed the order in which nullable arithmetic operations are realized; I made numerous mistakes moving that code around. It's some complicated code.

Eric Lippert
+1 What an honest reply. ;-)
Wim Hollebrandse
Is there a reason the behavior of Guids and strings are so different? Just implemented in different iterations instead of having the same implementation that a string can't be null and instead requires a nullable string instead and was never felt worthwhile for the breaking change?
Chris Marisic
@Chris - this glitch only impacts value-types. Strings are reference-types. `null` is (and always has been) perfectly valid for `string`.
Marc Gravell
@Chris, I have not had any Diet Dr. Pepper yet this morning, so I'm a bit slow. I cannot understand what you're asking. Are you asking why strings are reference types and guids are value types?
Eric Lippert
Really just goes back to I want `Nullable<string>` in .NET because for all intensive purposes string is made to by used as a primitive type even though it's truly a reference type but it's the only primitive type that doesn't allow `Nullable<T>` it's annoying to not be able to constrain whether null is a valid or invalid value of it and always having to do null checks where as every other object in my domain is guaranteed to be not null unless it's nullable and then I have GetValueOrDefault to leverage.
Chris Marisic
@Chris Marisic: `string` is not for all intents and purposes a primitive type. For example, `Frobber(s); // s is string` does not cause a copy of what `s` refers to to be made. The rest I don't understand; `string` is already "nullable" as it's a reference type.
Jason
@Jason, he's saying he wants a *non nullable* string type.
Eric Lippert
@Eric Lippert: Oh! You're right; I was not reading that correctly at all. Thank you.
Jason
Yes I believe that strings should behave the exact same way as Guids do. The fact they are immutable but still can be defined as null makes them some pseudo-primitive type that requires tons of custom coding to handle them which was clearly understood it would be that way when methods like `String.IsNullOrEmpty` exist and `String.Empty` exists.
Chris Marisic
+3  A: 

Jon Skeet has already answered this!

http://bytes.com/topic/c-sharp/answers/689783-null-guid

Will Vousden