92

I have the following line of code:

var connectionString = configItems.
                Find(item => item.Name.ToLowerInvariant() == "connectionstring");

VS 2010 code analysis is telling me the following:

Warning 7 CA1308 : Microsoft.Globalization : In method ... replace the call to 'string.ToLowerInvariant()' with String.ToUpperInvariant().

Does this mean ToUpperInvariant() is more reliable?

Otiel
  • 18,404
  • 16
  • 78
  • 126
JL.
  • 78,954
  • 126
  • 311
  • 459
  • 35
    Note, however, that using `string.Equals(item.Name, "connectionstring", StringComparison.OrdinalIgnoreCase)` is probably the best approach in this particular case. – Greg Beech May 10 '10 at 09:21
  • http://stackoverflow.com/questions/773703/normalization-of-strings-with-string-toupperinvariant – kenny Dec 01 '12 at 22:22

3 Answers3

125

Google gives a hint pointing to CA1308: Normalize strings to uppercase

It says:

Strings should be normalized to uppercase. A small group of characters, when they are converted to lowercase, cannot make a round trip. To make a round trip means to convert the characters from one locale to another locale that represents character data differently, and then to accurately retrieve the original characters from the converted characters.

So, yes - ToUpper is more reliable than ToLower.

In the future I suggest googling first - I do that for all those FxCop warnings I get thrown around ;) Helps a lot to read the corresponding documentation ;)

Dirk
  • 10,668
  • 2
  • 35
  • 49
TomTom
  • 61,059
  • 10
  • 88
  • 148
  • 13
    +1 for "Helps a lot to read the corresponding documentation" (and also for being absolutely correct...) – gehho May 10 '10 at 09:47
  • 2
    Correct, some Polish characters do not make the ToLower() round-trip. – Chris Ballance Aug 30 '13 at 13:53
  • 14
    @ChrisBallance & TomTom Could you provide an example where the round trip failure results in undesired behavior ? – Ohad Schneider Jul 05 '14 at 13:12
  • 40
    The 'I suggest googling first' remarks are so annoying and useless. This is the 1st google result. – Bartosz Nov 05 '19 at 10:12
  • 9
    I did google it, and I ended up here with the first result – Arina Feb 06 '20 at 00:45
  • -1: The rule is silly. The documentation you quoted has omissions. ToUpper is *not* universally more reliable than ToLower. LMGTFY is passé. – Ishmaeel Dec 07 '21 at 08:09
  • 1
    @OhadSchneider: When you normalize user-facing non-ascii strings such as titles, labels or error messages, the only thing that ensues is shits and giggles. The real problems start when you try to normalize identifying strings such as *file names* or *natural keys* that contain international characters. – Ishmaeel Dec 07 '21 at 08:20
  • googling advice is really helpful – Andrei Bozantan Feb 10 '23 at 13:14
26

Besides what TomTom says, .net is optimized for string comparison in upper case. So using upper invariant is theoretically faster than lowerinvariant.

This is indeed stated in CLR via C# as pointed out in the comments. Im not sure if this is of course really true since there is nothing to be found on MSDN about this topic. The string comparison guide on msdn mentions that toupperinvariant and tolowerinvariant are equal and does not prefer the former.

Ishmaeel
  • 14,138
  • 9
  • 71
  • 83
Henri
  • 5,065
  • 23
  • 24
  • +1 true. I actually read about that some days ago and was quite surprised that there is a difference. However, I think the difference should be pretty small. – gehho May 10 '10 at 09:46
  • Any reference to that? Doing .NET 10 years and being qconsidered verygood - I did not know that ;) Would love to have some reference. – TomTom May 10 '10 at 09:52
  • 2
    I think I saw that in CLR via C# (J Richter). Still prefer to use an explicit StringComparer though. – Phil Gan May 10 '10 at 10:03
0

There is nothing wrong with ToLowerInvariant() if that's what your code needs to do. Sure, it should not be used for string comparison, but that's not ALWAYS what it's for. I don't like the implementation of this rule (CA1308) in non-comparison scenarios.

David Bond
  • 149
  • 1
  • 9