CA1841: Preferujte metody Contains u Dictionary

Vlastnost Hodnota
ID pravidla CA1841
Název Preferujte metody Contains
Kategorie Výkon
Oprava, která může být destruktivní nebo nedestruktivní Nezlomitelný
Povoleno ve výchozím nastavení v .NET 10 Jako návrh
Příslušné jazyky C# a Visual Basic

Příčina

Toto pravidlo vyhledá volání metody Contains na kolekci Keys nebo Values v rámci IDictionary<TKey,TValue>, která by mohla být nahrazena voláním metody ContainsKey nebo ContainsValue na samotném slovníku.

Popis pravidla

Volání Contains na kolekci Keys nebo Values může být často dražší než volání ContainsKey nebo ContainsValue na samotném slovníku:

  • Mnoho implementací slovníku líně vytvářejí instance kolekcí klíčů a hodnot, což znamená, že přístup ke kolekci Keys nebo Values může vést k dodatečným alokacím.
  • Může se stát, že zavoláte rozšiřující metodu na IEnumerable<T>, pokud kolekce klíčů nebo hodnot používá explicitní implementaci rozhraní, aby skryla metody z ICollection<T>. To může vést ke snížení výkonu, zejména při přístupu ke kolekci klíčů. Většina implementací slovníku dokáže poskytnout rychlou kontrolu přítomnosti klíčů s časovou složitostí O(1), zatímco metoda rozšíření Contains na IEnumerable<T> obvykle provádí pomalou kontrolu s časovou složitostí O(n).

Jak opravit porušení

Chcete-li opravit porušení, nahraďte volání na dictionary.Keys.Contains nebo dictionary.Values.Contains voláním na dictionary.ContainsKey nebo dictionary.ContainsValue, v tomto pořadí.

Následující fragment kódu ukazuje příklady porušení a postup jejich opravy.

using System.Collections.Generic;
// Importing this namespace brings extension methods for IEnumerable<T> into scope.
using System.Linq;

class Example
{
    void Method()
    {
        var dictionary = new Dictionary<string, int>();

        //  Violation
        dictionary.Keys.Contains("hello world");

        //  Fixed
        dictionary.ContainsKey("hello world");

        //  Violation
        dictionary.Values.Contains(17);

        //  Fixed
        dictionary.ContainsValue(17);
    }
}
Imports System.Collection.Generic
' Importing this namespace brings extension methods for IEnumerable(Of T) into scope.
' Note that in Visual Basic, this namespace is often imported automatically throughout the project.
Imports System.Linq

Class Example
    Private Sub Method()
        Dim dictionary = New Dictionary(Of String, Of Integer)

        ' Violation
        dictionary.Keys.Contains("hello world")

        ' Fixed
        dictionary.ContainsKey("hello world")

        ' Violation
        dictionary.Values.Contains(17)

        ' Fixed
        dictionary.ContainsValue(17)
    End Sub
End Class

Kdy potlačit upozornění

Pokud příslušný kód není kritický pro výkon, je bezpečné potlačit upozornění z tohoto pravidla.

Potlačení upozornění

Pokud chcete pouze potlačit jedno porušení, přidejte do zdrojového souboru direktivy preprocesoru, abyste pravidlo zakázali a znovu povolili.

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

Pokud chcete pravidlo pro soubor, složku nebo projekt zakázat, nastavte jeho závažnost v none konfiguračním souboru.

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

Další informace naleznete v tématu Jak potlačit upozornění analýzy kódu.

Viz také