In C #, qual è la differenza tra ToUpper()
e ToUpperInvariant()
?
Puoi fare un esempio in cui i risultati potrebbero essere diversi?
In C #, qual è la differenza tra ToUpper()
e ToUpperInvariant()
?
Puoi fare un esempio in cui i risultati potrebbero essere diversi?
Risposte:
ToUpper
usa la cultura attuale. ToUpperInvariant
usa la cultura invariante.
L'esempio canonico è la Turchia, dove il maiuscolo di "i" non è "I".
Codice di esempio che mostra la differenza:
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);
}
}
Per ulteriori informazioni sul turco, consulta questo post sul blog Test Turchia .
Non sarei sorpreso di sapere che ci sono vari altri problemi di capitalizzazione attorno ai personaggi elisi, ecc. Questo è solo un esempio che conosco dalla cima della mia testa ... in parte perché mi ha morso anni fa a Java, dove ero superiore -casando una stringa e confrontandola con "MAIL". Non ha funzionato così bene in Turchia ...
ımage
come nome di campo Image
e Unity 3D spamming un errore interno alla console Unable to find key name that matches 'rıght'
su un Windows "inglese" con le impostazioni regionali della Turchia per data e ora. Sembra che a volte anche Microsoft non superi il test di Turchia, la lingua di un PC non è nemmeno turco, ma solo lol.
La risposta di Jon è perfetta. Volevo solo aggiungere che ToUpperInvariant
equivale a chiamare ToUpper(CultureInfo.InvariantCulture)
.
Questo rende l'esempio di Jon un po 'più semplice:
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 },
}
});
}
}
Ho anche usato New Times Roman perché è un carattere più interessante.
Ho anche impostare la Form
's Font
proprietà invece dei due Label
controlli perché la Font
proprietà è ereditata.
E ho ridotto alcune altre righe solo perché mi piace il codice compatto (esempio, non di produzione).
Non avevo davvero niente di meglio da fare al momento.
Inizia con MSDN
http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant.aspx
Il metodo ToUpperInvariant è equivalente a ToUpper (CultureInfo.InvariantCulture)
Solo perché un capitale che è 'I' in inglese, non sempre che lo rendono così.
String.ToUpper
e String.ToLower
può dare risultati diversi date culture diverse. L'esempio più noto è l'esempio turco , per il quale la conversione della "i" latina minuscola in maiuscola non comporta un "I" latino maiuscolo, ma nella "I" turca.
Quanto a me era confuso anche con l'immagine sopra ( sorgente ), ho scritto un programma (vedi il codice sorgente di seguito) per vedere l'output esatto per l'esempio turco:
# 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)
Come potete vedere:
Culture.CultureInvariant
lascia i caratteri turchi così come sonoToUpper
e ToLower
sono reversibili, ovvero minare un personaggio dopo averlo maiuscolo, lo riporta alla forma originale, purché per entrambe le operazioni sia stata usata la stessa cultura.Secondo MSDN , per Char.ToUpper e Char.ToLower i turchi e gli azeri sono le uniche culture interessate perché sono le uniche con differenze di involucro a carattere singolo. Per le stringhe, potrebbero esserci più culture interessate.
Codice sorgente di un'applicazione console utilizzata per generare l'output:
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 utilizza le regole della cultura invariante
non c'è differenza in inglese. solo nella cultura turca si può trovare una differenza.