Comparer des chaînes en C#

Tip

Cet article fait partie de la section Notions de base pour les développeurs qui connaissent déjà au moins un langage de programmation et apprennent C#. Si vous débutez avec la programmation, commencez par commencer par les didacticiels De prise en main .

Venant d’une autre langue ? C# == appliqué aux chaînes de caractères compare les valeurs, et non les références, tout comme equals en Java ou === en JavaScript. La principale différence est que C# vous permet de choisir entre une comparaison ordinale (binaire) et une comparaison sensible à la culture au moyen d’une valeur StringComparison.

Vous comparez des chaînes pour répondre à l’une des deux questions suivantes : ces deux chaînes sont-elles égales ? ou Dans quel ordre ces chaînes trient-elles ? C# vous permet de contrôler deux facteurs indépendants lorsque vous répondez à l’une ou l’autre question :

  • Sensibilité à la casse : si "Hello" et "hello" sont considérés comme identiques.
  • Type de comparaison : ordinal (comparez la valeur binaire de chaque caractère) ou prenant en charge la culture (appliquez les règles linguistiques d’une culture).

L’énumération StringComparison combine ces facteurs en une seule valeur que vous passez aux méthodes de comparaison.

Comparer pour l’égalité

La méthode String.Equals et l’opérateur == effectuent tous deux, par défaut, une comparaison sensible à la casse et ordinale. La comparaison ordinale vérifie la valeur binaire de chaque caractère, de sorte qu’elle est rapide et donne le même résultat sur chaque ordinateur. Vous pouvez expliciter votre intention en appelant la surcharge qui accepte une valeur StringComparison :

string root = @"C:\users";
string root2 = @"C:\Users";

// Equals and == both perform a case-sensitive, ordinal comparison.
Console.WriteLine(root.Equals(root2));
// => False
Console.WriteLine(root == root2);
// => False

// Pass a StringComparison value to state the intent explicitly.
Console.WriteLine(root.Equals(root2, StringComparison.Ordinal));
// => False

Pour ignorer la casse tout en conservant la sémantique ordinale, transmettez StringComparison.OrdinalIgnoreCase:

string root = @"C:\users";
string root2 = @"C:\Users";

// OrdinalIgnoreCase compares the binary values but ignores case.
bool equalIgnoringCase = string.Equals(root, root2, StringComparison.OrdinalIgnoreCase);
Console.WriteLine(equalIgnoringCase);
// => True

Comparer selon l’ordre de tri

Pour déterminer l’ordre de tri plutôt que l’égalité, utilisez String.Compare. Elle retourne un nombre négatif, zéro ou un nombre positif pour indiquer si la première chaîne trie avant, à la même position que ou après la seconde :

string first = "Avocado";
string second = "Banana";

// Compare returns a negative number, zero, or a positive number
// to indicate sort order. Specify the comparison type explicitly.
int order = string.Compare(first, second, StringComparison.Ordinal);
Console.WriteLine(order < 0
    ? $"'{first}' sorts before '{second}'."
    : $"'{first}' sorts at or after '{second}'.");
// => 'Avocado' sorts before 'Banana'.

Important

Compare et CompareTo utilisent par défaut une comparaison respectant la culture, tandis que Equals et == utilisent par défaut une comparaison ordinale. Pour éviter les surprises, transmettez une valeur explicite StringComparison afin que votre code indique le comportement souhaité.

Comparer avec des constantes à l’aide du filtrage par motif is ou switch

Lorsque la valeur que vous comparez est une constante, vous pouvez utiliser l’opérateuris avec un modèle constant comme alternative lisible à ==:

string status = "Ready";

// When the right operand is a constant, the is operator and a
// constant pattern read as an alternative to ==.
if (status is "Ready")
{
    Console.WriteLine("The system is ready.");
}
// => The system is ready.

Pour comparer une chaîne à plusieurs constantes, utilisez une switch expression. Chaque bras teste un modèle constant, et le modèle d’élément ignoré (_) gère chaque valeur qui ne correspond pas. L’exemple suivant associe un mot-clé de direction à une instruction de déplacement :

foreach (string heading in new[] { "North", "South", "East", "West", "NE" })
{
    // A switch expression matches each constant pattern in turn and
    // returns the first match. The discard (_) handles every other value.
    string instruction = heading switch
    {
        "North" => "Travel due North for 10 km.",
        "South" => "Travel due South for 10 km.",
        "East" => "Travel due East for 10 km.",
        "West" => "Travel due West for 10 km.",
        _ => $"Unknown heading: {heading}.",
    };
    Console.WriteLine(instruction);
}
// => Travel due North for 10 km.
// => Travel due South for 10 km.
// => Travel due East for 10 km.
// => Travel due West for 10 km.
// => Unknown heading: NE.

Une expression switch qui évalue des constantes de chaîne effectue la même comparaison ordinale sensible à la casse que == ; "north" ne correspond donc pas à la branche "North".

Choisir la comparaison appropriée

Choisissez le type de comparaison en fonction des données, et non pas par habitude :

  • Pour les identificateurs, les chemins d’accès aux fichiers, les jetons de protocole et d’autres textes définis par l’ordinateur, utilisez Ordinal (ou OrdinalIgnoreCase pour ignorer le cas). La comparaison ordinale est rapide et cohérente entre les cultures.
  • Pour le texte que les utilisateurs lisent et trient, tel que les noms ou les noms de produits, utilisez CurrentCulture afin que l’ordre corresponde aux attentes de l’utilisateur.

La comparaison tenant compte de la culture applique des règles linguistiques qui varient d’une culture à l’autre et peuvent produire des résultats surprenants. Par exemple, certaines cultures traitent "ss" et "ß" comme égales, et l’ordre des chaînes peut changer d’une machine à l’autre. En raison de cette variabilité, réservez une comparaison adaptée à la culture pour un texte en langage naturel authentique et utilisez le même type de comparaison chaque fois que vous triez et recherchez une collection.

Pour une présentation détaillée de la comparaison respectant la culture, y compris les considérations relatives à la mondialisation et les différences entre plateformes, consultez Meilleures pratiques pour comparer des chaînes dans .NET.

Voir aussi