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:
ToUpperusa la cultura attuale. ToUpperInvariantusa 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 ...
ımagecome nome di campo Imagee 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 ToUpperInvariantequivale 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 Fontproprietà invece dei due Labelcontrolli perché la Fontproprietà è 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.ToUppere String.ToLowerpuò 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 sonoToUppere ToLowersono 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.