tags:

views:

280

answers:

6

My code is...

    public static void AssertNotNull<T>(string name, T val)
    {
        if (val == null)
            throw new ArgumentNullException(String.Format("{0} must not be null", name));
    }

Resharper is recommending...

    public static void AssertNotNull<T>(string name, T val)
    {
        if (Equals(val, default(T)))
            throw new ArgumentNullException(String.Format("{0} must not be null", name));
    }
+11  A: 

Because it doesn't know if T is a value type or reference type, so it makes the code work with both.

Bearddo
so if i wanted to do the following to make sure it is a ref type, what do I put for XXX?public static void AssertNotNull<T>(string name, T val) where T : XXX
jayrdub
nm Michael Meadows answered that part
jayrdub
I actually disagree with Resharper in this case if that's why it's giving that error. Think about it, if T is an int, and the value IS actually 0 and SHOULD be zero, it will throw an exception, whereas if you check for null, it wouldn't throw an exception.
BFree
http://msdn.microsoft.com/en-us/library/6b0scde8(VS.80).aspx for more info as well
Bearddo
The suggestion is definitely wrong, but it does need to flag this, because it is a static code error. An API shouldn't allow a value type to call a method call AssertNotNull.
Michael Meadows
Whether or not that's what you want it to do is up to you, but that is why it's telling you to change it.
Bearddo
@jayrdub : "where T : class" . Then you can check against null.
flq
the problem is that example 1 _does_ allow you to check against null. In this case, it behaves correctly (any value type will pass the assertion). Resharper is just warning you because that may not have been what you intended. @BFree is right, though, in that the suggestion is wrong in this case.
Michael Meadows
+10  A: 

I second Berado's answer, but would add that you can prevent this by adding the constraint below:

public static void AssertNotNull<T>(string name, T val) where T : class
Michael Meadows
thanks, that makes a lot of sense
jayrdub
+1  A: 

Those two methods are not equivalent. The first one allows AssertNotNull( "foo", 0 ) while the second throws. I think Resharper is being overzealous in this case.

Greg
Your point is on spot. Resharper flags it as a warn (yellow) by default. It just wants to warn you that this method won't work as expected for all possible inputs.
Michael Meadows
er, one revision: AssertNotNull("foo", 0) will not throw an exception, it will act like it is a null value, since the default for int is 0, so therefore Equals(val, default(T)) evaluates to true.
Michael Meadows
I meant that "throw new ArgumentNullException" will be run in the second method. Do you agree?
Greg
+2  A: 

This obviously isn't what you want in this instance, but it's just trying to be helpful, making sure that you don't introduce a bug by forgetting that reference types can be used for T. Like @Michael Meadows said, you probably want to add the class constraint to T.

bdukes
A: 

I suppose because T could be a non-reference type.

Tundey
A: 

if you know that T will always be a class then add a where clause to say so then your origional code will be OK.

public static void AssertNotNull<T>(string name, T val)
    where T : class
    {
        if (val == null)
            throw new ArgumentNullException(String.Format("{0} must not be null", name));
    }
Damien McGivern