在 C # 中,ToUpper()和 ToUpper不变量()的区别是什么?

在 C # 中,ToUpper()ToUpperInvariant()的区别是什么?

你能举一个结果可能不同的例子吗?

69435 次浏览

ToUpper使用当前区域性。 ToUpperInvariant使用不变区域性。

典型的例子是土耳其,其中大写的“ i”不是“ 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);
}
}

有关土耳其语的更多信息,请参见此 土耳其试验博客文章

我不会感到惊讶,听到有各种其他大写问题周围省略字符等。这只是我第一时间知道的一个例子... ... 部分原因是因为几年前在 Java 中它咬了我一口,当时我正在对一个字符串进行大写并将其与“ MAIL”进行比较。这招在土耳其不管用。

从 MSDN 开始

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

方法是 等同于 ToUpper (CultureInfo. InvariantCulture)

仅仅因为大写字母 在英语中是 “我”,并不总是如此。

ToUpperInvariant使用来自 不变的文化不变的文化的规则

在英语中没有区别,只有在土耳其文化中才有区别。

乔恩的回答是完美的。我只是想补充说,ToUpperInvariant是相同的调用 ToUpper(CultureInfo.InvariantCulture)

这使得乔恩的例子更加简单:

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 },
}
});
}
}

我还使用了 新时代罗马,因为它是一种更酷的字体。

我还设置了 FormFont属性,而不是两个 Label控件,因为 Font属性是继承的。

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

我现在真的无事可做。

在不同的培养条件下,String.ToUpperString.ToLower可以给出不同的结果。最著名的例子是 土耳其的例子,其中将小写拉丁文“ i”转换为大写,不会产生大写拉丁文“ I”,而是产生土耳其文“ I”。

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

对我来说,即使是上面的图片(来源)也让我感到困惑,我编写了一个程序(见下面的源代码)来查看土耳其例子的确切输出:

# 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是可逆的,即在大写字符之后小写字符,使其恢复到原来的形式,只要两个操作使用相同的区域性。

根据 MSDN,对于 Char.ToUpperChar.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})";
}
}
}