33

I'm curious if any developers use string.IsNullOrEmpty() more often with a negative than with a positive

e.g.

if (!string.IsNullOrEmpty())

This is how I use the method 99% of the time. What was the design decision for this?

Chris S
  • 64,770
  • 52
  • 221
  • 239

14 Answers14

64

Because "IsNullOrEmpty" is easier to understand than "NotNullOrEmpty". The latter could be interpreted as:

  1. It's not null and it's not empty
  2. It's not null or it is empty
Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
38

Double negatives are usually discouraged in naming stuff. !string.NotNullOrEmpty(...) would make one.

Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
12

For those logicians out there, !string.IsNullOrEmpty is not equivalent to string.IsNotNullOrEmpty. @Guffa has it correct. Using DeMorgan's law, it would have to be string.IsNotNullAndNotEmpty to be equivalent.

¬(null ∨ empty) ⇔ ¬null ∧ ¬empty

¬(null ∨ empty) ≠ ¬null ∨ empty

The point here, I guess, is that the way it is currently is unambiguous, where as making the opposite unambiguous would be cumbersome.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
7

I always create an extension method for "HasContent()" which generally makes sense, follows the "positive" specifications, and saves on code bloat because I use it much more often than its counterpart:

public static bool HasContent(this string s) {
    return !string.IsNullOrEmpty(s);
}
sethjeffery
  • 71
  • 1
  • 1
  • Thank you. I was just thinking about the best name for this. I came up with "HasValue" and "IsPopulated," but HasContent is probably better than both. – Neil Oct 24 '11 at 19:57
  • I also add an IsEmpty() extension method for brevity and readability. I know people might complain about the word Null not being used, but I'm happy with this exception for the string class. – Aidan Jan 12 '18 at 13:26
7

C# naming conventions dictate that your expressions should be in the positive such as "Is..." and not "IsNot..."

EDIT: Typically, I use it when doing error checking and input validation at the beginning of a method and raise an exception if the parameter is null or empty.

if (string.IsNullOrEmpty(myParameter))
{
throw new ....
}

Erich Mirabal
  • 9,860
  • 3
  • 34
  • 39
7

I prefer the extension method:

public static class StringExtensions
{
    public static bool IsNullOrEmpty(this string value)
    {
        return string.IsNullOrEmpty(value);
    }
}

I find it reads better to say:

if(myValue.IsNullOrEmpty())

or

if(!myValue.IsNullOrEmpty())
Ðаn
  • 10,934
  • 11
  • 59
  • 95
Brian Genisio
  • 47,787
  • 16
  • 124
  • 167
  • 3
    @Dan: You can actually, http://stackoverflow.com/questions/647643/string-isnullorblank-extension-method. +1. – sipsorcery Apr 09 '09 at 14:13
  • 3
    @Dan: I suppose that is just philosophy... I have no problem with extension methods that work on null as long as it is clear in the method name: value.IsNull(), value.ThrowIfNull() or value.IsNullOrEmpty(). – Brian Genisio Apr 09 '09 at 14:43
  • 1
    But what do you think about extension methods that are specifically named *Null* ? – Brian Genisio Apr 09 '09 at 16:33
  • And that is where I disagree. What problem are you solving by not allowing foo.IsNull() ? To me, it is more readable. BTW, I agree with you with all other extension methods. – Brian Genisio Apr 09 '09 at 18:01
  • 2
    I'm sure that Uncle Bob would probably disapprove but I don't think that the sky will fall on our heads if we do foo.IsNull() - I would say it is pretty obvious what you are trying to achieve – Calanus Aug 19 '09 at 12:15
  • @Calanus: The issue is not with intent but with consistency. Usually if you call a method on an uninstantiated variable you get a null reference exception at run time. If you do the same thing with an extension method you don't. This kind of inconsistency makes it more difficult to spot wrong code which could lead to run time errors (the worst kind of error). Take a look at Joel's post on making bugs easier to spot: http://www.joelonsoftware.com/articles/Wrong.html – Phil Gan May 06 '10 at 12:12
  • @Phil: My argument is that when you call .IsNull() or .IsNullOrEmpty(), there IS consistency. The naming is consistent. Even the .Net framework is not consistent across the board. Look at nullable types, for instance. The following will throw a NRE on the second line: if(!nullableInt.HasValue) return nullableInt.GetType(); That is a heck of a lot less consistent than an extension method labeled .IsNullOrEmpty(). And it reads a heck of a lot better than the alternative. See http://jrwren.wrenfam.com/blog/2010/04/22/method-is-wish-was-there-ienumerable-isnullorempty/ as an example. – Brian Genisio May 06 '10 at 13:02
  • 1
    @Brian: I can see your point. Personally I don't think I'll ever be comfortable with calling methods on an uninstatiated variable because I think it sets an unsafe precedent. On an aside I'm quite disappointed that we can't create static extension methods - I'd like to be able to write `AType.IsNullOrEmpty(aVar);` on more types. – Phil Gan May 06 '10 at 13:28
4

Perhaps because then the name would have to be the lengthy IsNotNullAndNotEmpty to be as specific.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
2

Of course you could always use string.IsNullOrWhiteSpace(string) now instead of string .IsNullOrEmpty(string) from .NET 4.0

Binoj Antony
  • 15,886
  • 25
  • 88
  • 96
1

I would actually be inclined to offer a different answer from the "it's ambiguous" explanation provided by several others (though I agree with that answer as well):

Personally, I like to minimize nesting in my code, as (to me) the more curly braces code has, the harder it becomes to follow.

Therefore I'd much prefer this (for example):

public bool DoSomethingWithString(string s) {
    if (string.IsNullOrEmpty(s))
        return false;

    // here's the important code, not nested
}

to this:

public bool DoSomethingWithString(string s) {
    if (!string.IsNullOrEmpty(s)) {
        // here's the important code, nested
    } else {
        return false;
    }
}

This is a pretty specific scenario (where a null/empty string prompts an immediate exit) and clearly isn't the way a method using IsNullOrEmpty would always be structured; but I think it's actually pretty common.

Dan Tao
  • 125,917
  • 54
  • 300
  • 447
1

That is the most common usage I have seen.

John Kraft
  • 6,811
  • 4
  • 37
  • 53
1

"NotNullOrEmpty" is ambiguous, it could mean "(not null) or empty" or it could mean "not (null or empty)". To make it unambiguous you'd have to use "NotNullAndNotEmpty", which is a mouthfull.

Also, the "IsNullOrEmpty" naming encourages use as a guard clause, which I think is useful. E.g.:

if (String.IsNullOrEmpty(someString))
{
   // error handling
   return;
}
// do stuff

which I think is generally cleaner than:

if (!String.IsNullOrEmpty(someString))
{
   // do stuff
}
else
{
   // error handling
   return;
}
Wedge
  • 19,513
  • 7
  • 48
  • 71
0

I had the same question before I realized all I had to do to flip the question was to put the Not operator in front of the conditional. I think it cleande up my code some.

 // need to check if tBx_PTNum.Text is empty
        /*
        if (string.IsNullOrWhiteSpace(tBx_PTNum.Text))
        {
            // no pt number yet
        }
        else
        {
            ptNum = Convert.ToInt32(tBx_PTNum.Text);
        }
        */
        
        if(!string.IsNullOrEmpty(tBx_PTNum.Text))
        {
            ptNum = Convert.ToInt32(tBx_PTNum.Text);
        }
Greg
  • 1
0

Personally I prefer to cater for the non negated scenario first. It just makes sense to me to do the true part first and then the false. Comes down to personal style.

uriDium
  • 13,110
  • 20
  • 78
  • 138
0

I've always thought it seemed the wrong way round as I use the negative much more often than the positive.

I would also like there to be an instance IsEmpty() or IsNotEmpty() for use when the variable is declared within the function. This could not be IsNullOrEmpty() or IsNotNullOrEmpty() as if the instance was null then you would get a null reference exception.

stevehipwell
  • 56,138
  • 6
  • 44
  • 61