Udostępnij przez


CA1841: Preferuj słownik zawiera metody

Właściwości Wartość
Identyfikator reguły CA1841
Tytuł Preferuj słownik zawiera metody
Kategoria Wydajność
Poprawka powodująca niezgodność lub niezgodność Niezgodność
Domyślnie włączone na platformie .NET 10 Jako sugestia

Przyczyna

Ta reguła lokalizuje wywołania Contains metody w Keys kolekcji Values lub IDictionary<TKey,TValue> , która może zostać zastąpiona wywołaniem ContainsKey metody lub ContainsValue w samym słowniku.

Opis reguły

Wywoływanie Contains kolekcji Keys lub Values często jest droższe niż wywoływanie ContainsKey lub ContainsValue w samym słowniku:

  • Wiele implementacji słowników z opóźnieniem tworzy wystąpienia kolekcji kluczy i wartości, co oznacza, że uzyskanie Keys dostępu do kolekcji lub Values może spowodować dodatkowe alokacje.
  • Jeśli kolekcja kluczy lub wartości używa jawnej implementacji interfejsu w celu ukrycia metod w IEnumerable<T>obiekcie , może zakończyć się wywołaniem metody rozszerzenia .ICollection<T> Może to prowadzić do zmniejszenia wydajności, zwłaszcza w przypadku uzyskiwania dostępu do kolekcji kluczy. Większość implementacji słownika jest w stanie zapewnić szybkie sprawdzanie zawierania O(1) dla kluczy, podczas gdy Contains metoda rozszerzenia zwykle IEnumerable<T> wykonuje powolne sprawdzanie zawierania O(n).

Jak naprawić naruszenia

Aby rozwiązać problemy z naruszeniami, zastąp wywołania do dictionary.Keys.Contains lub dictionary.Values.Contains wywołaniami dictionary.ContainsKeydictionary.ContainsValuelub , odpowiednio.

Poniższy fragment kodu przedstawia przykłady naruszeń i sposób ich naprawiania.

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

Kiedy pomijać ostrzeżenia

Można bezpiecznie pominąć ostrzeżenia z tej reguły, jeśli w danym kodzie nie ma krytycznego dla wydajności.

Pomijanie ostrzeżenia

Jeśli chcesz po prostu pominąć pojedyncze naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć regułę.

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

Aby wyłączyć regułę dla pliku, folderu lub projektu, ustaw jego ważność na none w pliku konfiguracji.

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

Aby uzyskać więcej informacji, zobacz Jak pominąć ostrzeżenia dotyczące analizy kodu.

Zobacz też