В C# в чем разница между ToUpper() и ToUpperInvariant()?
В C# какая разница между ToUpper()
а также ToUpperInvariant()
?
Можете ли вы привести пример, где результаты могут отличаться?
7 ответов
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, где я был выше -составить строку и сравнить ее с "MAIL". Это не сработало так хорошо в Турции...
Ответ Джона идеален. Я просто хотел добавить, что 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 },
}
});
}
}
Я также использовал New Times Roman, потому что это более прохладный шрифт.
Я также установил Form
"s Font
собственность вместо двух Label
контролирует, потому что Font
собственность наследуется.
И я сократил несколько других строк только потому, что мне нравится компактный (например, не производственный) код.
У меня действительно не было ничего лучшего, чтобы сделать в данный момент.
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
являются обратимыми, то есть символ в нижнем регистре после символа в верхнем регистре приводит его к исходной форме, если для обеих операций использовалась одна и та же культура.
По данным 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})";
}
}
}
Начните с 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 объясняет различия и дает примеры отличающихся результатов.
Нет никакой разницы в английском. только в турецкой культуре можно найти разницу.