Most languages these days have some variation of "is string null or empty" as a convenience function. Certainly, C#, the language we're looking at today does. Let's look at a few example of how this can go wrong, from different developers.
We start with an example from Jason, which is useless, but not a true WTF:
/// <summary>
/// Does the given string contain any characters?
/// </summary>
/// <param name="strToCheck">String to check</param>
/// <returns>
/// true - String contains some characters.
/// false - String is null or empty.
/// </returns>
public static bool StringValid(string strToCheck)
{
if ((strToCheck == null) ||
(strToCheck == string.Empty))
return false;
return true;
}
Obviously, a better solution here would be to simply return the boolean expression instead of using a conditional, but equally obvious, the even better solution would be to use the built-in. But as implementations go, this doesn't completely lose the plot. It's bad, it shouldn't exist, but it's barely a WTF. How can we make this worse?
Well, Derek sends us an example line, which is scattered through the codebase.
if (Port==null || "".Equals(Port)) { /* do stuff */}
Yes, it's frequently done as a one-liner, like this, with the do stuff
jammed all together. And yes, the variable is frequently different- it's likely the developer responsible saved this bit of code as a snippet so they could easily drop it in anywhere. And they dropped it in everywhere. Any place a string got touched in the code, this pattern reared its head.
I especially like the "".Equals
call, which is certainly valid, but inverted from how most people would think about doing the check. It echos Python's string join
function, which is invoked on the join character (and not the string being joined), which makes me wonder if that's where this developer started out?
I'll never know.
Finally, let's poke at one from Malfist. We jump over to Java for this one. Malfist saw a function called checkNull
and foolishly assumed that it returned a boolean if a string was null.
public static final String checkNull(String str, String defaultStr)
{
if (str == null)
return defaultStr ;
else
return str.trim() ;
}
No, it's not actually a check. It's a coalesce function. Okay, misleading names aside, what is wrong with it? Well, for my money, the fact that the non-null input string gets trimmed, but the default string does not. With the bonus points that this does nothing to verify that the default string isn't null, which means this could easily still propagate null reference exceptions in unexpected places.
I've said it before, and I'll say it again: strings were a mistake. We should just abolish them. No more text, everybody, we're done.
