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:
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 ...
ımage
jako nazwę pola dla Image
Unity 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 ToUpperInvariant
to 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 Font
zamiast dwóch Label
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.
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.ToUpper
i String.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
i ToLower
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
oraz Char.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})";
}
}
}
ToUpperInvariant
używa reguł z niezmiennej kultury
nie ma różnicy w języku angielskim. tylko w kulturze tureckiej można znaleźć różnicę.