Comment : comparer des chaînes (Guide de programmation C#)
Lorsque vous comparez des chaînes, vous obtenez un résultat indiquant qu'une chaîne est supérieure ou inférieure à l'autre, ou que les deux chaînes sont égales.Les règles qui déterminent le résultat sont différentes selon que vous effectuez une comparaison ordinale ou une comparaison dépendante de la culture.Il est important d'utiliser le type correct de comparaison pour la tâche spécifique.
Utilisez la comparaison ordinale de base lorsque vous devez comparer ou trier les valeurs de deux chaînes sans tenir compte de conventions linguistiques.Les comparaisons ordinales de base (System.StringComparison.Ordinal) respectent la casse, ce qui signifie que les caractères des deux chaînes doivent correspondre : « et » n'est pas l'équivalent de « Et » ni de « ET ».Une variation fréquemment utilisée est System.StringComparison.OrdinalIgnoreCase, qui correspond à « et », « Et » et « ET ».StringComparison.OrdinalIgnoreCase est souvent utilisé pour comparer des noms de fichiers, des noms de chemins, des chemins d'accès réseau et d'autres chaînes dont la valeur ne change pas en fonction des paramètres régionaux de l'ordinateur de l'utilisateur.Pour plus d'informations, consultez System.StringComparison.
Les comparaisons dépendantes de la culture sont utilisées en général pour comparer et trier des chaînes entrées par les utilisateurs finals parce que les caractères et les conventions de tri de ces chaînes peuvent varier en fonction des paramètres régionaux de l'ordinateur de l'utilisateur.Même les chaînes qui contiennent des caractères identiques peuvent être triées différemment selon la culture du thread actuel.
[!REMARQUE]
Lorsque vous comparez des chaînes, vous devez utiliser les méthodes qui spécifient explicitement le type de comparaison que vous projetez d'effectuer.Cela rend votre code beaucoup plus facile à gérer et à lire.Dans la mesure du possible, utilisez les surcharges des méthodes des classes System.String et System.Array, qui acceptent les paramètres d'énumération StringComparison, afin que vous puissiez spécifier le type de comparaison à effectuer.Il vaut mieux éviter d'utiliser les opérateurs == et != lorsque vous comparez des chaînes.Évitez également d'utiliser les méthodes d'instance String.CompareTo parce qu'aucune des surcharges n'accepte de StringComparison.
Exemple
L'exemple suivant indique comment comparer correctement des chaînes dont les valeurs ne changent pas en fonction des paramètres régionaux de l'ordinateur de l'utilisateur.De plus, il montre également la fonctionnalité d'internement de chaîne de C#.Lorsqu'un programme déclare plusieurs variables chaîne identiques, le compilateur les stocke toutes au même emplacement.En appelant la méthode ReferenceEquals, vous constatez que les deux chaînes font en fait référence au même objet en mémoire.Utilisez la méthode String.Copy pour éviter l'internement, comme illustré dans l'exemple.
// Internal strings that will never be localized.
string root = @"C:\users";
string root2 = @"C:\Users";
// Use the overload of the Equals method that specifies a StringComparison.
// Ordinal is the fastest way to compare two strings.
bool result = root.Equals(root2, StringComparison.Ordinal);
Console.WriteLine("Ordinal comparison: {0} and {1} are {2}", root, root2,
result ? "equal." : "not equal.");
// To ignore case means "user" equals "User". This is the same as using
// String.ToUpperInvariant on each string and then performing an ordinal comparison.
result = root.Equals(root2, StringComparison.OrdinalIgnoreCase);
Console.WriteLine("Ordinal ignore case: {0} and {1} are {2}", root, root2,
result ? "equal." : "not equal.");
// A static method is also available.
bool areEqual = String.Equals(root, root2, StringComparison.Ordinal);
// String interning. Are these really two distinct objects?
string a = "The computer ate my source code.";
string b = "The computer ate my source code.";
// ReferenceEquals returns true if both objects
// point to the same location in memory.
if (String.ReferenceEquals(a, b))
Console.WriteLine("a and b are interned.");
else
Console.WriteLine("a and b are not interned.");
// Use String.Copy method to avoid interning.
string c = String.Copy(a);
if (String.ReferenceEquals(a, c))
Console.WriteLine("a and c are interned.");
else
Console.WriteLine("a and c are not interned.");
// Output:
// Ordinal comparison: C:\users and C:\Users are not equal.
// Ordinal ignore case: C:\users and C:\Users are equal.
// a and b are interned.
// a and c are not interned.
L'exemple suivant indique comment comparer des chaînes de la façon voulue en utilisant les méthodes System.String, qui acceptent les énumérations StringComparison.Notez que les méthodes d'instance String.CompareTo ne sont pas utilisées ici, parce qu'aucune des surcharges n'accepte de StringComparison.
// "They dance in the street."
// Linguistically (in Windows), "ss" is equal to
// the German essetz: 'ß' character in both en-US and de-DE cultures.
string first = "Sie tanzen in die Straße.";
string second = "Sie tanzen in die Strasse.";
Console.WriteLine("First sentence is {0}", first);
Console.WriteLine("Second sentence is {0}", second);
// Store CultureInfo for the current culture. Note that the original culture
// can be set and retrieved on the current thread object.
System.Threading.Thread thread = System.Threading.Thread.CurrentThread;
System.Globalization.CultureInfo originalCulture = thread.CurrentCulture;
// Set the culture to en-US.
thread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
// For culture-sensitive comparisons, use the String.Compare
// overload that takes a StringComparison value.
int i = String.Compare(first, second, StringComparison.CurrentCulture);
Console.WriteLine("Comparing in {0} returns {1}.", originalCulture.Name, i);
// Change the current culture to Deutch-Deutchland.
thread.CurrentCulture = new System.Globalization.CultureInfo("de-DE");
i = String.Compare(first, second, StringComparison.CurrentCulture);
Console.WriteLine("Comparing in {0} returns {1}.", thread.CurrentCulture.Name, i);
// For culture-sensitive string equality, use either StringCompare as above
// or the String.Equals overload that takes a StringComparison value.
thread.CurrentCulture = originalCulture;
bool b = String.Equals(first, second, StringComparison.CurrentCulture);
Console.WriteLine("The two strings {0} equal.", b == true ? "are" : "are not");
/*
* Output:
First sentence is Sie tanzen in die Straße.
Second sentence is Sie tanzen in die Strasse.
Comparing in current culture returns 0.
The two strings are equal.
*/
L'exemple suivant indique comment trier et rechercher des chaînes dans un tableau d'une manière dépendante de la culture, en utilisant les méthodes Array statiques, qui acceptent les paramètres System.StringComparer.
class SortStringArrays
{
static void Main()
{
string[] lines = new string[]
{
@"c:\public\textfile.txt",
@"c:\public\textFile.TXT",
@"c:\public\Text.txt",
@"c:\public\testfile2.txt"
};
Console.WriteLine("Non-sorted order:");
foreach (string s in lines)
{
Console.WriteLine(" {0}", s);
}
Console.WriteLine("\n\rSorted order:");
// Specify Ordinal to demonstrate the different behavior.
Array.Sort(lines, StringComparer.Ordinal);
foreach (string s in lines)
{
Console.WriteLine(" {0}", s);
}
string searchString = @"c:\public\TEXTFILE.TXT";
Console.WriteLine("Binary search for {0}", searchString);
int result = Array.BinarySearch(lines, searchString, StringComparer.OrdinalIgnoreCase);
ShowWhere<string>(lines, result);
//Console.WriteLine("{0} {1}", result > 0 ? "Found" : "Did not find", searchString);
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
// Displays where the string was found, or, if not found,
// where it would have been located.
private static void ShowWhere<T>(T[] array, int index)
{
if (index < 0)
{
// If the index is negative, it represents the bitwise
// complement of the next larger element in the array.
index = ~index;
Console.Write("Not found. Sorts between: ");
if (index == 0)
Console.Write("beginning of array and ");
else
Console.Write("{0} and ", array[index - 1]);
if (index == array.Length)
Console.WriteLine("end of array.");
else
Console.WriteLine("{0}.", array[index]);
}
else
{
Console.WriteLine("Found at index {0}.", index);
}
}
}
/*
* Output:
Non-sorted order:
c:\public\textfile.txt
c:\public\textFile.TXT
c:\public\Text.txt
c:\public\testfile2.txt
Sorted order:
c:\public\Text.txt
c:\public\testfile2.txt
c:\public\textFile.TXT
c:\public\textfile.txt
Binary search for c:\public\TEXTFILE.TXT
Found at index 2.
*/
Les classes de collection telles que System.Collections.Hashtable, System.Collections.Generic.Dictionary<TKey, TValue> et System.Collections.Generic.List<T> ont des constructeurs qui acceptent les paramètres System.StringComparer lorsque le type des éléments ou des clés est string.En général, vous devez utiliser ces constructeurs dès que cela est possible et spécifier Ordinal ou OrdinalIgnoreCase.
Voir aussi
Référence
System.Globalization.CultureInfo