CA2249: Erwägen Sie die Verwendung von "String.Contains" anstelle von "String.IndexOf"

Eigenschaft Wert
Regel-ID CA2249
Titel Erwägen Sie die Verwendung von "String.Contains" anstelle von "String.IndexOf"
Kategorie Verwendung
Fix führt oder führt nicht zur Unterbrechung Nicht unterbrechend
Standardmäßig in .NET 9 aktiviert Als Vorschlag

Ursache

Diese Regel sucht nach Aufrufen von IndexOf, wo das Ergebnis verwendet wird, um zu überprüfen, ob ein Substring vorhanden oder nicht vorhanden ist. Zudem empfiehlt sie stattdessen die Verwendung von Contains, um die Lesbarkeit zu verbessern.

Regelbeschreibung

Wenn IndexOf verwendet wird, um zu überprüfen, ob das Ergebnis gleich -1 oder größer oder gleich 0 ist, kann der Aufruf sicher durch Contains ersetzt werden, ohne dass sich dies auf die Leistung auswirkt.

Abhängig von der verwendeten Überladung IndexOf könnte für den vorgeschlagenen Fix ein Argument comparisonType hinzugefügt werden:

Überladung Vorgeschlagener Fix
String.IndexOf(char) String.Contains(char)
String.IndexOf(string) String.Contains(string, StringComparison.CurrentCulture)
String.IndexOf(char, StringComparison.Ordinal) String.Contains(char)
String.IndexOf(string, StringComparison.Ordinal) String.Contains(string)
String.IndexOf(char, NON StringComparison.Ordinal)* String.Contains(char, NON StringComparison.Ordinal)*
String.IndexOf(string, NON StringComparison.Ordinal)* String.Contains(string, NON StringComparison.Ordinal)*

* Alle StringComparison-Enumerationswerte außer StringComparison.Ordinal:

Behandeln von Verstößen

Der Verstoß kann entweder manuell behoben werden oder in einigen Fällen durch Quick Actions zum Beheben von Code in Visual Studio.

Beispiele

Die folgenden beiden Codeausschnitte zeigen alle möglichen Verstöße gegen die Regel in C# und wie sie behoben werden:

using System;

class MyClass
{
    void MyMethod()
    {
        string str = "My text";
        bool found;

        // No comparisonType in char overload, so no comparisonType added in resulting fix
        found = str.IndexOf('x') == -1;
        found = str.IndexOf('x') >= 0;

        // No comparisonType in string overload, adds StringComparison.CurrentCulture to resulting fix
        found = str.IndexOf("text") == -1;
        found = str.IndexOf("text") >= 0;

        // comparisonType equal to StringComparison.Ordinal, removes the argument
        found = str.IndexOf('x', StringComparison.Ordinal) == -1;
        found = str.IndexOf('x', StringComparison.Ordinal) >= 0;

        found = str.IndexOf("text", StringComparison.Ordinal) == -1;
        found = str.IndexOf("text", StringComparison.Ordinal) >= 0;

        // comparisonType different than StringComparison.Ordinal, preserves the argument
        found = str.IndexOf('x', StringComparison.OrdinalIgnoreCase) == -1;
        found = str.IndexOf('x', StringComparison.CurrentCulture) >= 0;

        found = str.IndexOf("text", StringComparison.InvariantCultureIgnoreCase) == -1;
        found = str.IndexOf("text", StringComparison.InvariantCulture) >= 0;

        // Suggestion message provided, but no automatic fix offered, must be fixed manually
        int index = str.IndexOf("text");
        if (index == -1)
        {
            Console.WriteLine("'text' Not found.");
        }
    }
}
using System;

class MyClass
{
    void MyMethod()
    {
        string str = "My text";
        bool found;

        // No comparisonType in char overload, so no comparisonType added in resulting fix
        found = !str.Contains('x');
        found = str.Contains('x');

        // No comparisonType in string overload, adds StringComparison.CurrentCulture to resulting fix
        found = !string.Contains("text", StringComparison.CurrentCulture);
        found = string.Contains("text", StringComparison.CurrentCulture);

        // comparisonType equal to StringComparison.Ordinal, removes the argument
        found = !string.Contains('x');
        found = string.Contains('x');

        found = !string.Contains("text");
        found = string.Contains("text");

        // comparisonType different than StringComparison.Ordinal, preserves the argument
        ;found = !string.Contains('x', StringComparison.OrdinalIgnoreCase)
        found = string.Contains('x', StringComparison.CurrentCulture);

        found = !string.Contains("text", StringComparison.InvariantCultureIgnoreCase);
        found = string.Contains("text", StringComparison.InvariantCulture);

        // This case had to be manually fixed
        if (!str.Contains("text"))
        {
            Console.WriteLine("'text' Not found.");
        }
    }
}

Tipp

Für diese Regel ist ein Codefix in Visual Studio verfügbar. Um ihn zu nutzen, muss der Cursor auf dem Verstoß platziert und STRG+. (Punkt) gedrückt werden. Wählen Sie aus der Liste der Optionen, die angezeigt werden, Erwägen Sie die Verwendung von "string.Contains" anstelle von "string.IndexOf" aus.

Codefix für CA2249: Erwägen Sie die Verwendung von

Wann sollten Warnungen unterdrückt werden?

Es ist sicher, einen Verstoß gegen diese Regel zu unterdrücken, wenn das Verbessern der Lesbarkeit von Code nicht relevant ist.

Unterdrücken einer Warnung

Um nur eine einzelne Verletzung zu unterdrücken, fügen Sie der Quelldatei Präprozessoranweisungen hinzu, um die Regel zu deaktivieren und dann wieder zu aktivieren.

#pragma warning disable CA2249
// The code that's violating the rule is on this line.
#pragma warning restore CA2249

Um die Regel für eine Datei, einen Ordner oder ein Projekt zu deaktivieren, legen Sie den Schweregrad in der Konfigurationsdatei auf none fest.

[*.{cs,vb}]
dotnet_diagnostic.CA2249.severity = none

Weitere Informationen finden Sie unter Vorgehensweise: Unterdrücken von Codeanalyse-Warnungen.

Siehe auch