2009-03-30 14 views
7

È possibile in C# utilizzare i caratteri UTF-32 non nel piano 0 come carattere?Caratteri C# e UTF-16

string s = ""; // valid 
char c = ''; // generates a compiler error ("Too many characters in character literal") 

E in s è rappresentato da due caratteri, non uno.

Edit: Voglio dire, c'è un carattere un tipo di stringa AN con supporto Unicode completo, UTF-32 o UTF-8 per carattere? Per esempio se voglio un ciclo for su utf-32 (forse non in plane0) caratteri in una stringa.

risposta

9

La classe string rappresenta un blocco di testo con codifica UTF-16 e ogni char in un string rappresenta un valore di codice UTF-16.

Sebbene non vi sia un tipo BCL che rappresenta un singolo punto di codice Unicode, esiste un supporto per i caratteri Unicode oltre il Piano 0 sotto forma di overload dei metodi che utilizza uno string e un indice invece di un solo char. Ad esempio, il metodo statico GetUnicodeCategory(char) nella classe System.Globalization.CharUnicodeInfo ha un corrispondente metodo GetUnicodeCategory(string,int) che riconoscerà un carattere semplice o una coppia surrogata che inizia con l'indice specificato.


per scorrere gli elementi di testo in un string, è possibile utilizzare i metodi della classe System.Globalization.StringInfo. Qui, un "elemento di testo" corrisponde a un singolo carattere come visualizzato sullo schermo. Ciò significa che caratteri semplici ("a"), combinazione di caratteri ("a\u0304\u0308" = "a & # x0304; & # x0308;") e coppie sostitutive ("\uD950\uDF21" = "& # xD950; & # xDF21;") saranno tutti considerati come un singolo elemento di testo.

In particolare, il metodo statico GetTextElementEnumerator consente di enumerare su ciascun elemento di testo in un string (vedere la pagina MSDN collegata per un esempio di codice).

+1

Buona presentazione dei fatti. Nota che C# ti permette di usare '" \ U00064321 "' (esattamente otto cifre esadecimali dopo '\ U') che è equivalente a' "\ uD950 \ uDF21" 'ma più facile da" capire "da un Unicode/UTF-32 punto di vista. Questo è un punto di codice in [piano 6] (https://en.wikipedia.org/wiki/Plane_ (Unicode) #Unassigned_planes). –

4

Conosco il problema solo da Java e ho controllato lo documentation on char prima di rispondere e in effetti il ​​comportamento è praticamente lo stesso in .NET/C# e Java.

Sembra che in effetti un char è definito per essere a 16 bit e sicuramente non può contenere nulla al di fuori del piano 0. Solo String/string è in grado di gestire questi personaggi. In un array char verrà rappresentato come two surrogate characters.

3

C# System.String supporto UTF-32 bene, ma non è possibile scorrere la stringa come se fosse un array di System.Char o utilizzare IEnumerable.

ad esempio:

// iterating through a string NO UTF-32 SUPPORT 
for (int i = 0; i < sample.Length; ++i) 
{ 
    if (Char.IsDigit(sample[i])) 
    { 
     Console.WriteLine("IsDigit"); 
    } 
    else if (Char.IsLetter(sample[i])) 
    { 
     Console.WriteLine("IsLetter"); 
    } 
} 

// iterating through a string WITH UTF-32 SUPPORT 
for (int i = 0; i < sample.Length; ++i) 
{ 
    if (Char.IsDigit(sample, i)) 
    { 
     Console.WriteLine("IsDigit"); 
    } 
    else if (Char.IsLetter(sample, i)) 
    { 
     Console.WriteLine("IsLetter"); 
    } 

    if (Char.IsSurrogate(sample, i)) 
    { 
     ++i; 
    } 
} 

nota la sottile differenza nel Char.IsDigit e Char.IsLetter chiama. E che String.Length è sempre il numero di "caratteri" a 16 bit, non il numero di "caratteri" nel senso UTF-32.

Off topic, ma il supporto UTF-32 non è necessario per un'applicazione per gestire le lingue internazionali, a meno che non si disponga di un business case specifico per un oscuro linguaggio storico/tecnico.

+0

Quello di cui stai parlando non è UTF-32, ma solo UTF-16 che contiene caratteri supplementari. In UTF-32, ogni carattere è memorizzato come quattro byte. Le stringhe .NET sono sempre UTF-16. –

+1

Invece di "con supporto UTF-32", l'esempio dovrebbe probabilmente leggere "con supporto per coppie surrogate" o "con supporto per caratteri reali, non solo blocchi di 16 bit di I-hope-this-char-is-in-the -BMP". – Triynko