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 8 Jako sugestia

Przyczyna

Ta reguła lokalizuje wywołania Contains metody w Keys kolekcji IDictionary<TKey,TValue> lub Values , 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 ICollection<T>obiekcie , może zakończyć się wywołaniem metody rozszerzenia .IEnumerable<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ż