tags:

views:

153

answers:

3
private static void SaveOrRemove<T>(string key, T value)
{
    if (value == null)
    {
        Console.WriteLine("Remove: " + key);
    }

    //...
}

If I call passing 0 to value: SaveOrRemove("MyKey", 0), the condition value == null is false, then CLR dont make a value == default(T). What really happens?

+6  A: 

The JIT compiler basically removes any comparisons with null when T is a non-nullable value type, assuming them all to be false. (Nullable value types will compare with the null value for that type, which is probably what you expect.)

If you want it to compare to the default value, you could use:

if (EqualityComparer<T>.Default.Equals(value, default(T))
{
    ...
}
Jon Skeet
As a side point you cannot have a null value type so it will never be equal to null
saret
I'm sure I've seen some cases where it fails, though - using boxing in the end.
Marc Gravell
@Marc: I'd be very interested to hear about those cases. @Saret: Well, you can have the null value for a *nullable* value type. I'll edit the answer to include those.
Jon Skeet
Whats the difference between EqualityComparer<T>.Default.Equals and object.Equals? I never used EqualityComparer<T>.Default
Fujiy
@Fujiy: Object.Equals will box its arguments, and won't tell you at compile-time if you're trying to compare inappropriate types. In most cases I *think* those will be the only differences, but importantly you can pass around an `IEqualityComparer<T>` if you need to - e.g. when constructing a map or set.
Jon Skeet
@Jon, my mistake, I forgot about Nullable<T> ... it's also a struct
saret
A: 

If you want default(T) you have to say it, not null which has its own meaning. If you want the ability to actually pass in a null in place of a value type, you should use Nullable<T> instead.

So, your code would become:

private static void SaveOrRemove<T>(string key, Nullable<T> value)
{
    if (!value.HasValue()) // is null
    {
        Console.WriteLine("Remove: " + key);
    }
    else
    {
        T val = value.Value;
        // ...
    }
}

Note that Nullable<T> is only useful with value types (structs, "builtins" other than string); for reference types you can't use it anyway.

MSDN link

Chris Charabaruk
I'd personally use `if (value != null)` in there, rather than explicitly calling `HasValue`. It's the same effect, but I happen to prefer the syntactic sugar around null :)
Jon Skeet
I need a method that accept class and struct. Its a Session Wrapper
Fujiy
@Jon Skeet: Me too, but I felt it's best to show what actually happens there.
Chris Charabaruk
+4  A: 

Your question is answered in section 7.9.6 of the C# specification:

If an operand of a type parameter type T is compared to null, and the runtime type of T is a value type, the result of the comparison is false.

Eric Lippert