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?
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?
Odpowiedzi:
ToUpperużywa aktualnej kultury. ToUpperInvariantuż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 ...
ımagejako nazwę pola dla ImageUnity 3D spamowanie wewnętrznego błędu konsoli Unable 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 ToUpperInvariantto to samo, co dzwonienie ToUpper(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's Fontzamiast dwóch Labelkontrolek, ponieważ Fontwł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.
Zacznij od MSDN
http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant.aspx
Metoda ToUpperInvariant jest równoważna z ToUpper (CultureInfo.InvariantCulture)
Tylko dlatego, że duże i to „ja” w języku angielskim, nie zawsze tak jest.
String.ToUpperi String.ToLowermoż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 zmianToUpperi ToLowersą 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.ToUpperoraz Char.ToLowerturecka 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})";
}
}
}
ToUpperInvariantużywa reguł z niezmiennej kultury
nie ma różnicy w języku angielskim. tylko w kulturze tureckiej można znaleźć różnicę.