Comparing Strings Like It's 1995
Posted in Development
While going through The Art of Unit Testing: with Examples in .NET this morning, I came across a string comparison notation, which always makes me cringe:
if (!fileName.ToLower().EndsWith (".slv")) { }
I’ve also lost count of seeing its closest cousin:
if (someText.ToLower() === "some test value") { }
This is how we used to roll in C++. I’m surprised anybody still does this.
For one, ToLower() doesn’t produce consistent results for several languages, e.g. Turkish (see The Motivation: The Turkish-I Problem).
ToLower() on a null, so you have to run null checks all over the place. Why not use string.Equals instead? It’s null-friendly.
In .NET, you should do culture-aware comparisons. With FxCop, every time you do otherwise, it will apply its Specify CultureInfo rule:
Because the behavior of ’string.ToLower()’ could vary based on the current user’s locale settings, replace this call in ’Foo()’ with a call to ’string.ToLower(CultureInfo)’. If the result of ’string.ToLower(CultureInfo)’ will be displayed to the user, specify ’CultureInfo.CurrentCulture’ as the ’CultureInfo’ parameter. Otherwise, if the result will be stored and accessed by software, such as when it is persisted to disk or to a database, specify ’CultureInfo.InvariantCulture’.”
Microsoft has an excellent whitepaper on MSDN, New Recommendations for Using Strings in Microsoft .NET 2.0. Read it and memorize it.
9 comments
Milan Negovan
on November 13, 2009
At the very least I'd do this:
fileName.EndsWith (".slv", StringComparison.OrdinalIgnoreCase)
RichB
on November 13, 2009
ToLowerInvariant() is a better choice if you must use ToLower()
roy
on November 14, 2009
so how would you drive such a change through TDD?
ToLower was the simplest in terms of funxtionality
Milan Negovan
on November 14, 2009
The MSDN article I referred to has a section, "What About the Earlier Recommendation for Invariant Culture?", about ToLowerInvariant. Its usage is discourage and kept only for backward compatibility.
Milan Negovan
on November 15, 2009
You still make an assumption about casing. And what if it contains non-Latin characters? This is why you need to perform culture-aware comparisons.
nic0428
on November 15, 2009
Its a shame how much "==" string comparison I've used for my .net projects. Thanks for sharing the idea!! The .NET article was great.
rtpHarry
on November 15, 2009
Interesting article. I do usually use .Equals rather than == just to avoid the possibility of accidentally assigning rather than comparing. I wasn't sure if there were any other technical reasons for this.
That book is high on my Christmas wish list as well...

Rik Hemsley
on November 13, 2009
Not disagreeing, but: How would this be a problem with the file extension comparison?