在C#中,ToUpper()和ToUpperInvariant()之间有什么区别?

时间:2010-08-23 17:49:30

标签: c# internationalization

在C#中,ToUpper()ToUpperInvariant()之间有什么区别?

您能举例说明结果可能会有所不同吗?

6 个答案:

答案 0 :(得分:138)

ToUpper使用当前的文化。 ToUpperInvariant使用不变文化。

典型的例子是土耳其,其中“i”的大写不是“我”。

显示差异的示例代码:

using System;
using System.Drawing;
using System.Globalization;
using System.Threading;
using System.Windows.Forms;

public class Test
{
    [STAThread]
    static void Main()
    {
        string invariant = "iii".ToUpperInvariant();
        CultureInfo turkey = new CultureInfo("tr-TR");
        Thread.CurrentThread.CurrentCulture = turkey;
        string cultured = "iii".ToUpper();

        Font bigFont = new Font("Arial", 40);
        Form f = new Form {
            Controls = {
                new Label { Text = invariant, Location = new Point(20, 20),
                            Font = bigFont, AutoSize = true},
                new Label { Text = cultured, Location = new Point(20, 100),
                            Font = bigFont, AutoSize = true }
            }
        };        
        Application.Run(f);
    }
}

有关土耳其语的更多信息,请参阅此Turkey Test blog post

我不会感到惊讶,因为有许多其他的大写问题围绕着被忽略的角色等等。这只是我不知道的一个例子...部分是因为它在几年前在Java中找到了我的位置我上面是一个字符串并将其与“MAIL”进行比较。这在土耳其没有那么好用......

答案 1 :(得分:25)

Jon的回答非常完美。我只想补充一点,ToUpperInvariant与调用ToUpper(CultureInfo.InvariantCulture)相同。

这让Jon的例子变得更简单了:

using System;
using System.Drawing;
using System.Globalization;
using System.Threading;
using System.Windows.Forms;

public class Test
{
    [STAThread]
    static void Main()
    {
        string invariant = "iii".ToUpper(CultureInfo.InvariantCulture);
        string cultured = "iii".ToUpper(new CultureInfo("tr-TR"));

        Application.Run(new Form {
            Font = new Font("Times New Roman", 40),
            Controls = { 
                new Label { Text = invariant, Location = new Point(20, 20), AutoSize = true }, 
                new Label { Text = cultured, Location = new Point(20, 100), AutoSize = true }, 
            }
        });
    }
}

我还使用了 New Times Roman 因为它是一个更酷的字体。

我还设置了Form的{​​{1}}属性而不是两个Font控件,因为Label属性是继承的。

我减少了一些其他行只是因为我喜欢紧凑(例如,不是生产)代码。

此刻我真的没有更好的事情要做。

答案 2 :(得分:15)

从MSDN开始

http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant.aspx

  

ToUpperInvariant方法是   相当于   ToUpper的(CultureInfo.InvariantCulture)

仅仅因为大写 i '我'的英语,并不总能如此。

答案 3 :(得分:6)

String.ToUpperString.ToLower可以根据不同的文化给出不同的结果。最着名的例子是the Turkish example,为此转换小写拉丁语" i"大写,不会导致大写拉丁语"我",但在土耳其语" I"。

Capitalization of I depending on culture, upper row - lower case letters, lower row - upper case letters

至于我,即使上面的图片(source)也很混乱,我写了一个程序(参见下面的源代码)来查看土耳其语示例的确切输出:

# Lowercase letters
Character              | UpperInvariant | UpperTurkish | LowerInvariant | LowerTurkish
English i - i (\u0069) | I (\u0049)     | I (\u0130)   | i (\u0069)     | i (\u0069)
Turkish i - ı (\u0131) | ı (\u0131)     | I (\u0049)   | ı (\u0131)     | ı (\u0131)

# Uppercase letters
Character              | UpperInvariant | UpperTurkish | LowerInvariant | LowerTurkish
English i - I (\u0049) | I (\u0049)     | I (\u0049)   | i (\u0069)     | ı (\u0131)
Turkish i - I (\u0130) | I (\u0130)     | I (\u0130)   | I (\u0130)     | i (\u0069)

如你所见:

  1. 大写小写字母和小写大写字母给不变文化和土耳其文化带来不同的结果。
  2. 无论文化是什么,大写字母大写和小写字母小写都没有效果。
  3. Culture.CultureInvariant保留土耳其字符
  4. ToUpperToLower是可逆的,即在对其进行大写之后小写字符,将其带到原始形式,只要两种操作都使用相同的文化。
  5. 根据MSDN,Char.ToUpper和Char.ToLower土耳其语和阿塞拜疆语是唯一受影响的文化,因为它们是唯一具有单字符套管差异的文化。对于字符串,可能会有更多文化受到影响。

    用于生成输出的控制台应用程序的源代码:

    using System;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    
    namespace TurkishI
    {
        class Program
        {
            static void Main(string[] args)
            {
                var englishI = new UnicodeCharacter('\u0069', "English i");
                var turkishI = new UnicodeCharacter('\u0131', "Turkish i");
    
                Console.WriteLine("# Lowercase letters");
                Console.WriteLine("Character              | UpperInvariant | UpperTurkish | LowerInvariant | LowerTurkish");
                WriteUpperToConsole(englishI);
                WriteLowerToConsole(turkishI);
    
                Console.WriteLine("\n# Uppercase letters");
                var uppercaseEnglishI = new UnicodeCharacter('\u0049', "English i");
                var uppercaseTurkishI = new UnicodeCharacter('\u0130', "Turkish i");
                Console.WriteLine("Character              | UpperInvariant | UpperTurkish | LowerInvariant | LowerTurkish");
                WriteLowerToConsole(uppercaseEnglishI);
                WriteLowerToConsole(uppercaseTurkishI);
    
                Console.ReadKey();
            }
    
            static void WriteUpperToConsole(UnicodeCharacter character)
            {
                Console.WriteLine("{0,-9} - {1,10} | {2,-14} | {3,-12} | {4,-14} | {5,-12}",
                    character.Description,
                    character,
                    character.UpperInvariant,
                    character.UpperTurkish,
                    character.LowerInvariant,
                    character.LowerTurkish
                );
            }
    
            static void WriteLowerToConsole(UnicodeCharacter character)
            {
                Console.WriteLine("{0,-9} - {1,10} | {2,-14} | {3,-12} | {4,-14} | {5,-12}",
                    character.Description,
                    character,
                    character.UpperInvariant,
                    character.UpperTurkish,
                    character.LowerInvariant,
                    character.LowerTurkish
                );
            }
        }
    
    
        class UnicodeCharacter
        {
            public static readonly CultureInfo TurkishCulture = new CultureInfo("tr-TR");
    
            public char Character { get; }
    
            public string Description { get; }
    
            public UnicodeCharacter(char character) : this(character, string.Empty) {  }
    
            public UnicodeCharacter(char character, string description)
            {
                if (description == null) {
                    throw new ArgumentNullException(nameof(description));
                }
    
                Character = character;
                Description = description;
            }
    
            public string EscapeSequence => ToUnicodeEscapeSequence(Character);
    
            public UnicodeCharacter LowerInvariant => new UnicodeCharacter(Char.ToLowerInvariant(Character));
    
            public UnicodeCharacter UpperInvariant => new UnicodeCharacter(Char.ToUpperInvariant(Character));
    
            public UnicodeCharacter LowerTurkish => new UnicodeCharacter(Char.ToLower(Character, TurkishCulture));
    
            public UnicodeCharacter UpperTurkish => new UnicodeCharacter(Char.ToUpper(Character, TurkishCulture));
    
    
            private static string ToUnicodeEscapeSequence(char character)
            {
                var bytes = Encoding.Unicode.GetBytes(new[] {character});
                var prefix = bytes.Length == 4 ? @"\U" : @"\u";
                var hex = BitConverter.ToString(bytes.Reverse().ToArray()).Replace("-", string.Empty);
                return $"{prefix}{hex}";
            }
    
            public override string ToString()
            {
                return $"{Character} ({EscapeSequence})";
            }
        }
    }
    

答案 4 :(得分:3)

ToUpperInvariant使用invariant culture

中的规则

答案 5 :(得分:2)

英语没有区别。只有在土耳其文化中才能找到差异。