Official Guidance: New Recommendations for Strings in .NET 2.0 [Dave Fetterman]

The BCL Team has here published new official guidance for using Strings in .NET 2.0. It is highly recommended that .NET developers use these new best practices and new Framework types when developing on the second major version of the Framework.

The full paper can be found here: https://msdn.microsoft.com/netframework/default.aspx?pull=/library/en-us/dndotnet/html/StringsinNET20.asp

The following is a snippet of the paper:

Introduction

The Microsoft .NET Framework enables developers to create software fully ready for localization and internationalization, through comprehensive machinery under the hood designed for, among other tasks, correctly interpreting strings given the current locale. This aids in quickly creating and using solutions designed for a broad range of cultures. But, when culturally-irrelevant string data is interpreted by these methods, code can exhibit subtle bugs and operate slower than necessary on untested cultures.

When interpreting strings, the canonical example of a culturally-aware type, sometimes flipping the culture switch causes unexpected results. The same strings can sort, case, and compare differently under different Thread.CurrentCulture settings. Sometimes strings should be allowed to vary according to the user's culture (for display data), but for most strings internal to an application, such as XML tags, user names, file paths, and system objects, the interpretation should be consistent throughout all cultures. Additionally, when strings represent such symbolic information, comparison operations should be interpreted entirely non-linguistically.

Recommendations for String Use

When developing with the 2.0 version of the .NET Framework, keeping a few very simple recommendations in mind will suffice to solve confusion about using strings.

  • DO: Use StringComparison.Ordinal or OrdinalIgnoreCase for comparisons as your safe default for culture-agnostic string matching.
  • DO: Use StringComparison.Ordinal and OrdinalIgnoreCase comparisons for increased speed.
  • DO: Use StringComparison.CurrentCulture-based string operations when displaying the output to the user.
  • DO: Switch current use of string operations based on the invariant culture to use the non-linguistic StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase when the comparison is linguistically irrelevant (symbolic, for example).
  • DO: Use ToUpperInvariant rather than ToLowerInvariant when normalizing strings for comparison.
  • DON'T: Use overloads for string operations that don't explicitly or implicitly specify the string comparison mechanism.
  • DON'T: Use StringComparison.InvariantCulture-based string operations in most cases; one of the few exceptions would be persisting linguistically meaningful but culturally-agnostic data.

Many new and recommended String method overloads consume a StringComparison parameter, making these choices explicit:

Example 1:

 String protocol = MyGetUrlProtocol(); 

if (String.Compare(protocol, "ftp", StringComparsion.Ordinal) != 0)
{
   throw new InvalidOperationException();
}

Example 2:

 String filename = args[0];
StreamReader reader;

if (String.EndsWith(filename, "txt", StringComparison.OrdinalIgnoreCase))
{
   reader = File.OpenText(filename);   
}