W języku C # jaka jest różnica między ToUpper()
i ToUpperInvariant()
?
Czy możesz podać przykład, w którym wyniki mogą być inne?
c#
internationalization
Lill Lansey
źródło
źródło
Odpowiedzi:
ToUpper
używa aktualnej kultury.ToUpperInvariant
używa niezmiennej kultury.Kanonicznym przykładem jest Turcja, gdzie duże litery „i” nie są „I”.
Przykładowy kod pokazujący różnicę:
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); } }
Więcej informacji na temat języka tureckiego można znaleźć w tym poście na blogu dotyczącym Turcji .
Nie zdziwiłbym się słysząc, że są różne inne problemy z wielkimi literami wokół znaków elided itp. To tylko jeden przykład, który znam z całego serca ... częściowo dlatego, że ugryzł mnie wiele lat temu w Javie, gdzie byłem wyżej -casowanie łańcucha i porównywanie go z "MAIL". To nie działało tak dobrze w Turcji ...
źródło
ımage
jako nazwę pola dlaImage
Unity 3D spamowanie wewnętrznego błędu konsoliUnable to find key name that matches 'rıght'
w „angielskim” systemie Windows z regionalnymi ustawieniami daty i godziny dla Turcji. Wygląda na to, że czasami nawet Microsoft nie zdaje testu Turcji, język komputera nie jest nawet turecki, tylko lol.Odpowiedź Jona jest doskonała. Chciałem tylko dodać, że
ToUpperInvariant
to to samo, co dzwonienieToUpper(CultureInfo.InvariantCulture)
.To sprawia, że przykład Jona jest trochę prostszy:
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 }, } }); } }
Użyłem też New Times Roman, ponieważ jest to fajniejsza czcionka.
Ustawiłem również właściwość
Form
'sFont
zamiast dwóchLabel
kontrolek, ponieważFont
właściwość jest dziedziczona.I zredukowałem kilka innych wierszy tylko dlatego, że lubię kod kompaktowy (na przykład nie produkcyjny).
W tej chwili naprawdę nie miałem nic lepszego do roboty.
źródło
Zacznij od MSDN
http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant.aspx
Tylko dlatego, że duże i to „ja” w języku angielskim, nie zawsze tak jest.
źródło
String.ToUpper
iString.ToLower
może dać różne wyniki w różnych kulturach. Najbardziej znanym przykładem jest turecki przykład , w którym zamiana małej litery „i” na wielkie litery nie daje łacińskiego „I” pisanego wielką literą, ale tureckie „I”.Jak dla mnie było to mylące nawet z powyższym obrazkiem ( źródło ), napisałem program (patrz kod źródłowy poniżej), aby zobaczyć dokładne dane wyjściowe dla przykładu tureckiego:
# 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)
Jak widzisz:
Culture.CultureInvariant
pozostawia znaki tureckie bez zmianToUpper
iToLower
są odwracalne, to znaczy małe litery po wielkich literach, doprowadzają go do pierwotnej postaci, o ile dla obu operacji użyto tej samej kultury.Według MSDN , kultury for
Char.ToUpper
orazChar.ToLower
turecka i azerska to jedyne kultury, których dotyczy problem, ponieważ są jedynymi, w których występują różnice w wielkości liter. W przypadku łańcuchów może to dotyczyć większej liczby kultur.Kod źródłowy aplikacji konsolowej użytej do wygenerowania wyniku:
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})"; } } }
źródło
ToUpperInvariant
używa reguł z niezmiennej kulturyźródło
nie ma różnicy w języku angielskim. tylko w kulturze tureckiej można znaleźć różnicę.
źródło