在C#中ToUpper()和ToUpperInvariant()有什么区别?
在C#中, ToUpper()
和ToUpperInvariant()
什么ToUpperInvariant()
?
你能举一个例子,结果可能会有所不同吗?
ToUpper
使用当前的文化。 ToUpperInvariant
使用不变的文化。
典型的例子是土耳其,“我”的大写字母不是“我”。
显示差异的示例代码:
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); } }
有关土耳其语的更多信息,请参阅土耳其考试博客
我不会惊讶地发现围绕这些被隐藏的人物还有其他各种各样的大写字母问题。这只是我头顶上的一个例子,部分原因是因为它在几年前在Java中占据了我的位置, – 把一个string和“MAIL”比较。 这在土耳其并没有那么好
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
的Font
属性而不是两个Label
控件,因为Font
属性是inheritance的。
而且我减less了一些其他的行,因为我喜欢紧凑的(例如,不是生产)代码。
我现在真的没有什么好做的了。
从MSDN开始
http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant.aspx
ToUpperInvariant方法等同于ToUpper(CultureInfo.InvariantCulture)
只因为资本我是英文的“我” ,并不总是如此。
http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant.aspx
Microsoft文档解释了差异,并给出了不同结果的示例。
ToUpperInvariant使用来自不变文化的规则
英语没有区别。 只有土耳其文化才能find差异。
对于不同的文化, String.ToUpper
和String.ToLower
可以给出不同的结果。 最着名的例子就是土耳其的例子 ,为了将小写的拉丁文“i”转换成大写,不会导致大写的拉丁文“I”,而是土耳其文中的“I”。
就我而言,即使是上面的图片( 源代码 )也是令人困惑的,我写了一个程序(见下面的源代码)来看看土耳其例子的确切输出:
# 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)
如你看到的:
- 大写的小写字母和小写的大写字母给不变的文化和土耳其文化带来不同的结果。
- 大写字母大写和小写字母小写字母无论文化是什么都不起作用。
-
Culture.CultureInvariant
土耳其字符 -
ToUpper
和ToLower
是可逆的,也就是说,在将这个字符大写后,将它们降低到原来的forms,只要对于两个操作使用相同的文化。
根据MSDN的说法,对于Char.ToUpper和Char.ToLower,土耳其语和阿塞拜疆语是唯一受影响的文化,因为它们是唯一具有单一字符shell差异的文化。 对于string,可能会有更多的文化受到影响。
用于生成输出的控制台应用程序的源代码:
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})"; } } }