StringInfo et TextElementEnumerator sont maintenant conformes à UAX29

Avant ce changement, System.Globalization.StringInfo et System.Globalization.TextElementEnumerator ne géraient pas correctement tous les clusters graphèmes. Certains graphèmes ont été fractionnés en composants constitutifs au lieu d’être conservés ensemble. Maintenant, StringInfo et TextElementEnumerator traitent les clusters graphèmes selon la dernière version de la norme Unicode.

En outre, la méthode Microsoft.VisualBasic.Strings.StrReverse, qui inverse les caractères d’une chaîne en Visual Basic, suit désormais également la norme Unicode pour les clusters graphèmes.

Description de la modification

Un graphème ou cluster graphème étendu est un caractère unique perçu par l’utilisateur qui peut être composé de plusieurs points de code Unicode. Par exemple, la chaîne contenant le caractère thaïlandais « kam » (กำ) se compose des deux caractères suivants :

  • ก (= '\u0e01') THAI CHARACTER KO KAI
  • ำ (= '\u0e33') THAI CHARACTER SARA AM

Lorsqu’il est affiché à l’utilisateur, le système d’exploitation combine les deux caractères pour former le caractère d’affichage unique (ou graphème) « kam » ou กำ. L’Emoji peut également se composer de plusieurs caractères qui sont combinés pour un affichage similaire.

Conseil

La documentation .NET utilise parfois le terme « élément texte » lorsque vous faites référence à un graphème.

Les classes StringInfo et TextElementEnumerator inspectent les chaînes et retournent des informations sur les graphèmes qu’elles contiennent. Dans .NET Framework (toutes les versions) et .NET Core 3.x et versions antérieures, ces deux classes utilisent une logique personnalisée qui gère certaines classes de combinaison, mais qui n’est pas entièrement conforme à la norme Unicode. Par exemple, les classes StringInfo et TextElementEnumerator fractionnent incorrectement le caractère thaïlandais unique « kam » en ses composants constitutifs au lieu de les conserver ensemble. Ces classes ont également fractionné incorrectement le caractère emoji « 🤷🏽 » en quatre clusters (haussement de personne, modificateur de la couleur de la peau, modificateur de sexe et combinaison invisible) au lieu de les garder ensemble comme un seul cluster graphème.

À compter de .NET 5, les classes StringInfo et TextElementEnumerator implémentent la norme Unicode telle que définie par l’annexe norme Unicode #29, rev. 35, sec. 3. En particulier, ils retournent désormais des clusters graphème étendus pour toutes les classes de combinaison.

Prenons le code C# suivant :

using System.Globalization;

static void Main(string[] args)
{
    PrintGraphemes("กำ");
    PrintGraphemes("🤷🏽‍♀️");
}

static void PrintGraphemes(string str)
{
    Console.WriteLine($"Printing graphemes of \"{str}\"...");
    int i = 0;

    TextElementEnumerator enumerator = StringInfo.GetTextElementEnumerator(str);
    while (enumerator.MoveNext())
    {
        Console.WriteLine($"Grapheme {++i}: \"{enumerator.Current}\"");
    }

    Console.WriteLine($"({i} grapheme(s) total.)");
    Console.WriteLine();
}

Dans .NET Framework et .NET Core 3.x et les versions antérieures, les graphèmes sont fractionnés et la sortie de la console est la suivante :

Printing graphemes of "กำ"...
Grapheme 1: "ก"
Grapheme 2: "ำ"
(2 grapheme(s) total.)

Printing graphemes of "🤷🏽‍♀️"...
Grapheme 1: "🤷"
Grapheme 2: "🏽"
Grapheme 3: "‍"
Grapheme 4: "♀️"
(4 grapheme(s) total.)

Dans .NET 5 et versions ultérieures, les graphèmes sont conservés ensemble et la sortie de la console est la suivante :

Printing graphemes of "กำ"...
Grapheme 1: "กำ"
(1 grapheme(s) total.)

Printing graphemes of "🤷🏽‍♀️"...
Grapheme 1: "🤷🏽‍♀️"
(1 grapheme(s) total.)

En outre, à compter de .NET 5, la méthode Microsoft.VisualBasic.Strings.StrReverse, qui inverse les caractères d’une chaîne dans Visual Basic, suit désormais également la norme Unicode pour les clusters graphèmes.

Ces changements font partie d’un ensemble plus large d’améliorations Unicode et UTF-8 dans .NET, notamment une API d’énumération de cluster graphème étendue pour compléter les API d’énumération de valeurs scalaires Unicode introduites avec le type System.Text.Rune dans .NET Core 3.0.

Version introduite

.NET 5.0

Aucune action de votre part n’est nécessaire. Vos applications se comportent automatiquement d’une manière plus conforme aux normes dans divers scénarios liés à la mondialisation.

API affectées