2009-12-12 5 views
6

J'essaie de gérer au caractère suivant: ⨝ (http://www.fileformat.info/info/unicode/char/2a1d/index.htm)chaîne.Empty.StartsWith (((char) 10781) .ToString()) renvoie toujours vrai?

Si vous vérifier si une chaîne vide en commençant par ce caractère, il retourne toujours vrai, cela ne fait aucun sens! Pourquoi donc?

// visual studio 2008 hides lines that have this char literally (bug in visual studio?!?) so i wrote it's unicode instead. 
char specialChar = (char)10781; 
string specialString = specialChar.ToString(); 

// prints 1 
Console.WriteLine(specialString.Length); 

// prints 10781 
Console.WriteLine((int)specialChar); 

// prints false 
Console.WriteLine(string.Empty.StartsWith("A")); 

// both prints true WTF?!? 
Console.WriteLine(string.Empty.StartsWith(specialString)); 
Console.WriteLine(string.Empty.StartsWith(((char)10781).ToString())); 

Répondre

11

Vous pouvez corriger ce bug en utilisant ordinal StringComparison:

A partir de la documentation MSDN:

Lorsque vous spécifiez soit StringComparison.Ordinal ou StringComparison.OrdinalIgnoreCase, la comparaison de chaînes sera non -linguistique. En d'autres termes, les fonctions spécifiques au langage naturel sont ignorées lors de la prise de décisions de comparaison . Cela signifie que les décisions sont basées sur les comparaisons simples byte et ignorent le casing ou tables d'équivalence qui sont paramétrisés par culture. En conséquence, en définissant explicitement le paramètre à soit le StringComparison.Ordinal ou StringComparison.OrdinalIgnoreCase, votre code gagne souvent la vitesse, augmente exactitude, et devient plus fiable.

char specialChar = (char)10781; 


    string specialString = Convert.ToString(specialChar); 

    // prints 1 
    Console.WriteLine(specialString.Length); 

    // prints 10781 
    Console.WriteLine((int)specialChar); 

    // prints false 
    Console.WriteLine(string.Empty.StartsWith("A")); 

    // prints false 
    Console.WriteLine(string.Empty.StartsWith(specialString, StringComparison.Ordinal)); 
+0

La comparaison sensible à la culture par défaut semble être une grande violation désastreuse du principe de la moindre surprise. Existe-t-il une règle empirique pour déterminer quelles méthodes nécessitent un StringComparison pour obtenir un comportement ordinal «normal» et lesquelles ne le font pas? – bobince

+0

@ bobince- avez-vous vu cette question- http: // stackoverflow.com/questions/72696/qui-est-généralement-meilleur-à-utiliser-chaînecomparison-ordinalignorecase-ou-stringcom – RichardOD

4

pépin Nice unicode ;-P

Je ne sais pas pourquoi il fait cela, mais d'une manière amusante:

Console.WriteLine(string.Empty.StartsWith(specialString)); // true 
Console.WriteLine(string.Empty.Contains(specialString)); // false 
Console.WriteLine("abc".StartsWith(specialString)); // true 
Console.WriteLine("abc".Contains(specialString)); // false 

Je devine que cela est traité un peu comme le non joindre le caractère Jon mentioned at devdays; certaines fonctions de chaîne le voient, et d'autres non. Et s'il ne le voit pas, cela devient "does (une chaîne de caractères) commence par une chaîne vide", qui est toujours true.

+0

+1 de moi. Je n'avais pas vu la conversation de Jon. – RichardOD

4

La raison sous-jacente est la comparaison de chaîne par défaut est locale au courant. Cela signifie utiliser des tables de données locales pour les comparaisons (y compris l'égalité). Beaucoup de caractères Unicode (si ce n'est la plupart) n'ont pas de valeur pour beaucoup de paramètres régionaux, et donc n'existent pas (ou font, mais correspondent à n'importe quoi, ou rien).

Voir les entrées sur les poids de caractères sur le blog de Michael Kaplan "Sorting It All Out". This series de blogs contient beaucoup d'informations de fond (les API sont natifs, mais — comme je comprends — les mécanismes dans .NET sont les mêmes).

Version abrégée: ceci est une zone complexe pour obtenir des comparaisons attendues (langage normal) à droite est difficile, cela a tendance à conduire à des choses étranges avec des points de code pour les glyphes en dehors de votre langue.

Questions connexes