tags:

views:

997

answers:

8

I'm just interested in people's opinions. When using nullable types in C# what is the best practice way to test for null:

bool isNull = (i == null);

or

bool isNull = !i.HasValue;

Also when assigning to a non-null type is this:

long? i = 1;
long j = (long)i;

better than:

long? i = 1;
long j = i.Value;
+7  A: 

I would always use the (i==null) form. It expresses what you are doing.

WRT the second question, I think either form is fine. However I'd always check it against null first and take appropriate action - perhaps wrapping that check and action up in a helper method (often it just sets a default value).

Phil Nash
A: 

They're both the same, but I would use the former version on both, since it's more common in the language: comparison to null and casting to a type.

Omer van Kloeten
A: 

I usually tend to lean towards the first option in both scenarios, since it's more 'primitive' oriented opposed to object oriented (which was really what we were going for), but it really doesn't matter that much

John
+11  A: 

I would use this:

long? i = 1;
...some code...
long j = i ?? 0;

That means, if i is null, than 0 will be assigned.

Seiti
also, if you're looking to assign the default for that value type (which may or may not be 0) you can use long j = i ?? default(long);
Lloyd Cotten
The problem that I have with trhat form is that not all developers will know what is going on immediately.
Ed Swangren
Very cool - I had not discovered the ?? operator or "default" yet.
Sam Schutte
@Ed Swangren, Professional .net programmers should be expected to know what the null coalescing operator is. Just like I would expect a C developer to know the bit-shifting operators. Don't code to the lowest commond denominator of programmers who haven't learned something.
Simucal
I might do that - but it depends if 0 is an acceptable sentinel value.
mackenir
By converting null to 0 you are in fact hiding an exception. This may be appropriate, it depends if you can assume a default value. Also whether you should use the ?? operator wasn't really part of my question.
Martin Brown
+3  A: 

I haven't used Nullable Types in practice, but for the second, I'd actually suggest using j.GetValueOrDefault(). The documentation suggests that the latter would actually throw an InvalidOperationException in the event of a null value. Depending on the internal implementation of the explict cast operator for long?, the former might, too. I'd stick with GetValueOrDefault and treat the null/default case appropriately.

Marc Bollinger
+4  A: 

Use the forms that were specially implemented for you by the C# team. If anyone objects, tell them Anders said it was okay.

What I'm saying, flippantly, is that a lot of work went into integrating nullable types into c# to give you a good programming experience.

Note that in terms of performance, both forms compile down to the same IL, ie:

int? i = 1;
bool isINull = i == null;
int j = (int)i;

Ends up like this after the C# compiler has got to it:

int? i = 1;
bool isINull = !i.HasValue;
int j = i.Value;
mackenir
+1  A: 

I tend to use the first on both, because as it needs to be supported later in its life-cycle, these seem easier to understand what the intent of the original writer.

Fry
A: 

Opened up Reflector. HasValue is a lookup on a boolean flag which is set when the value is changed. So in terms of cycles a lookup is going to be faster then compare.

public Nullable(T value)
{
    this.value = value;
    this.hasValue = true;
}

private bool hasValue;

internal T value;

public bool HasValue
{
    get
    {
        return this.hasValue;
    }
}
AdamSane
Have you checked what the comparison compiles down to? I'd be surprised if the syntactic sugar ended up as anything other than a call to HasValue.
mackenir