Search code examples
c#lowercasecultureinvariantculture

ToLowerInvariant from a Kelvin Sign (K) in C# has different results


When I define the kelvin-sign (http://www.unicode-symbol.com/u/212A.html) like this:

var kelvinSign = "K";

And do a console writeline:

Console.WriteLine("{0} - {1}=>ToLower={2} - {3}=>ToLowerInvariant={4}",
                kelvinSign,
                kelvinSign.ToLower(), kelvinSign.ToLower() == "k",
                kelvinSign.ToLowerInvariant(), kelvinSign.ToLowerInvariant() == "k");

I get on one PC this output:

  • K - k=>ToLower=True - K=>ToLowerInvariant=False

And on another PC I get:

  • K - k=>ToLower=True - k=>ToLowerInvariant=True

Which indicates that the ToLowerInvariant() method does work differently?


Notes

  • on both systems the Thread.CurrentThread.CurrentCulture andThread.CurrentThread.UICurrentCulture is the same : "en-US"
  • both are running net5.0

Update
System that works has these settings:

  • OS = "Windows 10 PRO"
UseNls = False
CultureInfo.InvariantCulture =
CultureInfo.InvariantCulture.Name =
CultureInfo.InvariantCulture.CultureTypes = SpecificCultures, InstalledWin32Cultures
CultureInfo.InvariantCulture.DisplayName = Unknown language
CultureInfo.InvariantCulture.TwoLetterISOLanguageName = iv
CultureInfo.InvariantCulture.ThreeLetterISOLanguageName = ivl
CurrentCulture   = en-US
CurrentUICulture = en-US
K - k=>ToLower=True - k=>ToLowerInvariant=True

System that does not work has these settings:

  • OS = "Windows Server 2019" (actually this is a build-agent from Azure)
UseNls = True
CultureInfo.InvariantCulture = 
CultureInfo.InvariantCulture.Name = 
CultureInfo.InvariantCulture.CultureTypes = SpecificCultures, InstalledWin32Cultures
CultureInfo.InvariantCulture.DisplayName = Invariant Language (Invariant Country)
CultureInfo.InvariantCulture.TwoLetterISOLanguageName = iv
CultureInfo.InvariantCulture.ThreeLetterISOLanguageName = ivl
CurrentCulture   = en-US
CurrentUICulture = en-US
K - k=>ToLower=True - K=>ToLowerInvariant=False

Solution

  • The reason for this question was that I want to run the full test-set for XPath 2.0 in my unit-tests for XPath2.Net and have the same results on all systems.

    But the XQTS_1_0_2 : caselessmatch04 had different results.

    This is because my local development system is "Windows 10 Pro" and the build-agent from Azure has "Windows Server 2019", so my solution was to detect if Nls was used. For this I used the code example from canton7:

    public static class GlobalizationUtils
    {
        public static bool UseNls()
        {
            return (typeof(CultureInfo).Assembly.GetType("System.Globalization.GlobalizationMode")
                ?.GetProperty("UseNls", BindingFlags.Static | BindingFlags.NonPublic)
                ?.GetValue(null) as bool?) == true;
        }
    }