Les chaînes et le contexte linguistique
Par amethyste le Nov 6, 2008 | Dans focus | Réagir »
Les méthodes de manipulation de chaînes (StartWith, Equals, Compare…) ont évoluées avec le framework 2.0 afin de clarifier la prise en charge du contexte linguistique de l'application.
En parallèle, Microsoft a mis à jour ses recommandations [1] d'usage. C'est ce que nous allons examiner dans cet article.
Pour vous convaincre de ne pas abandonner tout de suite une lecture peut être austère, voici le genre de bug subtil qui pourrait vous arriver si vous ne prenez pas les bonnes précautions:
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); Console.WriteLine("Culture = {0}", Thread.CurrentThread.CurrentCulture.DisplayName); Console.WriteLine("(file == FILE) = {0}", (String.Compare("file", "FILE", true) == 0)); Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR"); Console.WriteLine("Culture = {0}", Thread.CurrentThread.CurrentCulture.DisplayName); Console.WriteLine("(file == FILE) = {0}", (String.Compare("file", "FILE", true) == 0));
On compare les mots file et FILE dans un contexte culturel US puis turc. On obtient:
Culture = English (United State)
(file == FILE) = True
Culture = Turkish (Turkey)
(file == FILE) = False
Imaginez maintenant que l'on compare des mots de passe par exemple…
Les bonnes précautions, quelles sont t'elles au juste?
D'une façon générale il est recommandé d'utiliser systématiquement les surcharges des méthodes avec le paramètre du type StringComparison.
Il s'agit d'une énumération prenant ses valeurs dans la liste suivante:
1. Ordinal
2. OrdinalIgnoreCase
3. CurrentCulture
4. CurrentCultureIgnoreCase
5. InvariantCulture
6. InvariantCultureIgnoreCase
Microsoft recommande d'utiliser a priori l'une des deux premières valeurs, ce qui convient dans la plupart des cas. La comparaison est effectuée au niveau des octets, il s'agit donc d'une comparaison très rapide.
De fait le bug se résout effectivement avec OrdinalIgnoreCase.
L'implémentation actuelle des méthodes sans surcharge utilise CurrentCulture. Mais la version 4.0 du framework utilisera Ordinal[2] à l'exception de CompareTo et Compare puisque ces méthodes sont en général utilisées pour des opérations de tri.
Il est donc important de prendre l'habitude de se servir des variantes avec surcharge ne serai-ce que pour faciliter la maintenance, c'est toujours sain d'être clair sur ses intentions, ou bien de développer des classes utilitaires.
Par ailleurs Equals utilise non pas CurrentCulture, mais Ordinal. Ce qui fait une complication supplémentaire lorsqu'on utilise les méthodes sans surcharge.
Initialement Microsoft recommandait d'utiliser l'option InvariantCulture. Le problème est que cette option amène .NET à effectuer certains choix conduisant de ce fait à des résultats parfois imprévisibles lorsque les caractères manipulés n'appartiennent pas au jeu de caractères ASCII.
Vous trouverez en [1] un tableau récapitulatif des cas d'utilisation des valeurs de StringComparison.
Bibliographie
[1] http://msdn.microsoft.com/fr-fr/library/ms973919(en-us).aspx
[2] http://blogs.msdn.com/bclteam/default.aspx
Aucun commentaire pour le moment
Laisser un commentaire
| « Ma semaine au TechEd | Retour sur le ViewState » |