tags:

views:

731

answers:

6

Let's say I have two strings: a and b. To compare whether a and be have the same values when case is ignored, I've always used:

// (Assume a and b have been verified not to be null)

if (a.ToLower() == b.ToLower())

However, using Reflector, I've seen this a few times in the .NET Framework:

// (arg three is ignoreCase)

if (string.Compare(a, b, true) == 0)

I tested which is faster, and the ToLower() beat Compare() everytime with the strings I used.

Is there a reason why to Compare() instead of ToLower()? Something about different CultureInfo? I'm scratching my head.

A: 

ToLower() is not a comparison function, it puts the string to lower case. When the == operator is used on String objects in C# it is optimized by the compiler. At the core, Both depend on System.String.Equals as seen in Reflector.

John T
He meant the ToLower() example beat the (explicit) Compare() example.
strager
@Chris, Internationalization may play a role in this.
strager
Okay, then string.Compare(a.ToLower(), b.ToLower()) appears to be faster than string.Compare(a, b, true) then.
Chris
That's what I'm thinking.
Chris
+9  A: 

The main thing you should be concerned about isn't performance, it's correctness, and from that aspect the method you probably want to be using for a case insensitive comparison is either:

string.Compare(a, b, StringComparison.OrdinalIgnoreCase) == 0;

or

a.Equals(b, StringComparison.OrdinalIgnoreCase)

(The first one is useful if you know the strings may be null; the latter is simpler to write if you already know that at least one string is non-null. I've never tested the performance but assume it will be similar.)

Ordinal or OrdinalIgnoreCase are a safe bet unless you know you want to use another comparison method; to get the information needed to make the decision read this article on MSDN.

Greg Beech
+1 here - performance just doesn't matter. And if you reach a point where using a slightly-less string comparison method is causing performance problems, you need to rethink your approach.
Rex M
+1  A: 

When comparing strings you should always use an explicit StringComparison member. The String functions are somewhat inconsistent in how they choose to compare strings. The only way to guarantee the comparision used is to a) memorize all of them (this includes both you and everyone on your team) or b) use an explicit comparison for every function.

It's much better to be explicit and not rely on group knowledge being perfect. Your teammates will thank you for this.

Example:

if ( StringComparison.OrdinalIgnoreCase.Equals(a,b) )

Using ToLower for comparison has 2 problems I can think of off the top of my head

  1. It allocates memory. Comparison functions should not allocate memory unless they absolutely have to.
  2. Strings can be lowered in several ways. Most notable Ordinal or Culture Sensitive lower. Which way does .ToLower() work? Personally, I don't know. It's much better to pass an explicit culture than rely on the default.
JaredPar
+3  A: 

The Remarks section of the MSDN article should explain things. Essentially, the reason is for compatibility across different cultures settings.

Noldorin
A: 

Another MSDN article that provides some DOs and DON'Ts and recommendations for what comparison method to use in various cases: New Recommendations for Using Strings in Microsoft .NET 2.0

it depends
A: 

Could your post your test that shows calling ToLower() is faster than a case-insensitive comparison? My tests show the opposite to be true! Regardless, other posters' points about correctness stand.

Jim Arnold