IMO when checking if a string is "set":
- Simply using
bla is null
/bla is not null
is idealbla == null
/bla != null
is functionally equivalent for strings. For other types, "==" and "!=" could theoretically have a slow or incorrect override.is null
/is not null
is generally preferable since it ignores overrides.
string.IsNullOrWhiteSpace(bla)
is generally wrong- In some contexts,
string.IsNullOrEmpty()
does make sense
In most code that accepts input from other code (i.e. not a human), it is more elegant only use null
to indicate the absence of a value, and not empty strings or whitespace:
- That's literally what
null
means - In C#, you can use operators like
?.
and??
- In C# 8.0, you can use nullable reference types, which obviates argument checking althogether in a lot of places (especially lower in the stack)
- If an argument should be set to a non-
null
value, but we forget to validate, and the value isnull
, the code often fails fast with aNullReferenceException
. Failing fast is good.
Special-casing empty and whitespace also adds extra equivalence classes for testing, which people generally neglect to test:
null
- Empty string
- Whitespace-only strings
- Non-empty strings padded with whitespace
- Other non-empty strings
If you do have unsanitized input where empty strings and whitespace should be considered equivalent to null
, consider normalizing them to null
once at each boundary high in the stack, so that you can use simple null checks everywhere else.
In some cases (unsanitized input hand-typed by a human) it might be good to treat " "
as ""
, but that leads to a rabbit hole that most people would rather avoid:
- Should you sanitize
" a "
to"a"
withstring.Trim()
? - What about "a b" vs. "a b" or "a,b" the vs. "a, b "?
In other cases, whitespace might be relevant (e.g. linux file names). An empty or whitespace value may be semantically different from the lack of a value (i.e. null). Ignoring whitespace may lead to a gap in functionality in your API.
Sometimes you're better off treating both empty and null as unset, to match existing code or conventions.
For example, if you're writing C# code that interops with PowerShell, you may want to use string.IsNullOrEmpty()
to match this super common PowerShell idiom:
if ($bla) { <# do something when set #> }
which is equivalent (when $bla
is a [string]
) to:
if ([string]::IsNullOrEmpty($bla) { <# do something when set #> }