views:

376

answers:

5

I'm just writing a bit of code to compare an id of integer with an id of integer? for example:

Dim id As Integer = 1
Dim nullId As Integer? = Nothing
Dim areEqual As Boolean
areEqual = nullId = id

When I try to compile the code I get a compiler error:

Option Strict On disallows implicit conversions from 'Boolean?' to 'Boolean'.

Whilst it's very simple for me to work around this, I was hoping that someone might be able to explain what's going in the compiler to give this warning.

+3  A: 

This is an unfortunate consequence of the way the compiler generates the operators for nullable types. You can work around it by using the following code:

Dim AreEqual As Boolean = If(nullId, 0) = id

The If here corresponds to C#'s null coalesce operator and is a shortcut for:

Dim AreEqual As Boolean = If(nullId.HasValue, nullId.Value, 0) = id
Konrad Rudolph
A: 

You are trying to compare a type (integer) to a nullable type (integer?).

You need to check the actual value of nullID, but don't forget you'll need to check for nullId being null.

ChrisF
A: 

The compiler error happens because Option Strict On disallows implicit conversions from 'Boolean?' to 'Boolean'. And you are trying to assign a 'Boolean?' (the result of 'Integer?'='Integer') into a 'Boolean'.

Implicit conversions are typically disabled, in language standards, to avoid unintended mistakes. Adding an explicit conversion is easy; finding what implicit conversion you put in your code without knowing it may be hard.

A nullable type and an ordinary type are different enough to avoid implicit conversions between them.

Daniel Daranas
I think you missed the meat of the question, the code deals with integer and integer?, the error reported is for boolean?
Binary Worrier
"integer = integer?" results in a "boolean?", and the user is trying to assign it to a "boolean". But yes, I had missed that detail in the first place :)
Daniel Daranas
+6  A: 

It's one of the quirks of nullable types. NULL (in general terms) means "don't know". Comparing known with unknown results in unknown (because you don't know if they're the same).

It's the same with nullable types in .NET. Comparing an Integer? with an Integer results in a Boolean?, because you might get True, False or "don't know".

Roger Lipscombe
What about FileNotFound? ;-)
Konrad Rudolph
For those that missed the reference: http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
Roger Lipscombe
A: 

Null has the value "I don't know what the value is" and by definition any operation where one of the operands is null results in null. E.g. 2 = null results in null and hence the resulting value from int = int? has to have null as possible value and not just have the values true and false. bool? is the type that has just that set of values and therefor that is the return type of the operation.

The only implicit casts allowed are those that will always work. you can implicitly cast an int to a long. but not a long to an int (you can do that explicitly) because the latter could result in loss of information E.g. if the number is larger than int.MaxValue. In this case you would be trying to unbox a null value which would lead to a run-time exception.

Rune FS