views:

113

answers:

5

I'm trying to find the right thing to do with a non-null validation on a nullable boolean. I also want to be able to do the same thing with some other fields, including strings, ints, etc., so I want to use generics for the method. Here's an example of the kind of thing which can happen.

bool? myValue = null;
bool valid = ValidateNotNull(myValue);

And here's some validation code:

public bool ValidateNotNull<T>(T nullableField)
{
    return nullableField != null;
}

All the answers I've found to this kind of problem suggest adding a where T : struct or where T: class to the method signature, or using default(T) in the comparison, none of which will work for a bool where false is a valid value.

Any other suggestions? The code compiles, but Resharper isn't happy about that null comparison on a value which it thinks might be a primitive, and I'd love to know what I should be doing to cheer it up.

NB: This isn't the complete code. I'm still interested in maintaining the type. This is also not the only place I've run into the problem.

NB2: Yes, it compiles and works fine. What I really want to know is whether there is a code solution for stopping Resharper from complaining, or an idiomatic way to do this which I don't know about.

A: 

You need to use

public bool ValidateNotNull<T>(T nullableField)
{
    return nullableField.HasValue;
} 
Ashley
This does not compile!
Arcturus
Yes, Yes it does. Stop marking down if you got no clue.
Ashley
+1  A: 
Arcturus
No, because some of the fields I'm passing in might be 0 or false, which are valid. It's only null which is invalid.
Lunivore
Ahh ok.. updated my answer! :)
Arcturus
Your update is incorrect. The first part is returning `true` if `T` is a value type. `System.Nullable<>` is a value type, so `bool? bar = null` would be evaluated by your method to be not null.
Anthony Pegram
Dunno whether this was your original answer but I thought I'd give it a go, and it works - unit testing rocks. False and default(bool?) are not the same. Thank you! This solves my problem and I learnt a little more about C#! (And it does work - bool? bar = null does evaluate to null.)
Lunivore
You are right.. so I changed the code to IsPrimitive.. That should do the trick!
Arcturus
Either way, the Type class holds the answer :)
Arcturus
It works without the IsPrimitive I think. I'm not actually worried about primitives being passed in, since I'll only be validating fields which are nullable anyway - but I was worried about default(T) being false for bool? which was nonsense on my part. This is exactly what I needed to know.
Lunivore
Just for clarity in case anyone else finds this, the comparison I'm making in the question was `== default(T)` which definitely doesn't compile. Arcturus, your first example works fine for me, and I imagine the second will be useful in other situations. Thanks so much!
Lunivore
@Lunivore: the test for IsPrimitive is indeed redundant.
Ruben
+4  A: 

The code below will validate nullable types and reference types:

 public bool ValidateNotNull<T>(Nullable<T> nullableField) where T:struct
 {
  return nullableField.HasValue;
 }

 public bool ValidateNotNull<T>(T nullableField) where T:class
 {
  return nullableField!=null;
 }
Sean
Doesn't compile for bool? though.
Lunivore
It does on my machine!
Sean
Ah, you're right - I didn't spot that they were actually different implementations as well as different signatures. I prefer just having one method, but this is also beautiful so have an upvote.
Lunivore
+2  A: 

I also want to be able to do the same thing with some other fields, including strings, ints, etc

OK, so you want a method that can be passed either a Nullable<> (which is a struct), or a reference type, and will return true iff the argument is null (note that your name appears to be the wrong way round, but there you go).

The thing is, if that's all this method has to do, then you don't need generics because you don't need type-safety. This example works and does what you want, I think:

class Program
{
    static void Main(string[] args)
    {
        int? x = null;
        int? y = 5;
        string s = null;
        string r = "moo";

        Console.WriteLine(ValidateNotNull(x));
        Console.WriteLine(ValidateNotNull(y));
        Console.WriteLine(ValidateNotNull(s));
        Console.WriteLine(ValidateNotNull(r));

        Console.ReadLine();

    }

    private static bool ValidateNotNull(object o)
    {
        return o == null;
    }
}

This outputs

True
False
True
False

which is I believe your required output.

AakashM
Simple and elegant.
jdv
Hm, okay - I actually use the fact that it's a boolean elsewhere; this isn't the complete code, nor is it the only time I've run into this problem. I'm still looking for a way to maintain the type without having to cast. Thanks for the note on the != (copying and pasting from code which does some slightly different stuff!)
Lunivore
A: 

I don't know why you thing your method doesn't work (apart from using != rather than ==), because as far as I can tell, it already works! You can compare any value of type T with null (when T is a generic type parameter). If a non-nullable value type is used for T, the result will be treated as a constant (false for == null, true for != null).

So, this should be fine.

public bool ValidateNotNull<T>(T nullableField)
{
    return nullableField != null;
}

But this would also work without generics:

public bool ValidateNotNull(object nullableField)
{
    return nullableField != null;
}

(Because boxing a Nullable<T> null value returns a null reference.)

Ruben
Like I said, it compiles and works fine - but Resharper complains.
Lunivore
In that case, use the second solution (with object, not T)
Ruben