Udostępnij za pośrednictwem


CA1841: Preferuj słownik zawiera metody

Właściwości Wartość
Identyfikator reguły CA1841
Tytuł Preferuj używanie metod Contains dla słowników
Kategoria Wydajność
Poprawka łamiąca lub nienaruszająca Niezgodność
Domyślnie włączone na platformie .NET 10 Jako sugestia
Zastosowane języki C# i Visual Basic

Przyczyna

Ta reguła lokalizuje wywołania metody Contains na kolekcji Keys lub Values obiektu IDictionary<TKey,TValue>, które mogą zostać zastąpione wywołaniem metody ContainsKey lub ContainsValue na 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 inicjalizuje leniwie obiekty kolekcji kluczy i wartości, co oznacza, że dostęp do kolekcji Keys lub Values może spowodować dodatkowe alokacje.
  • Jeśli kolekcja kluczy lub wartości używa jawnej implementacji interfejsu, aby ukryć metody w IEnumerable<T> obiekcie, możesz skończyć na wywołaniu metody rozszerzenia na 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 umożliwia szybkie sprawdzanie obecności O(1) dla kluczy, podczas gdy metoda rozszerzenia Contains zazwyczaj wykonuje wolne sprawdzanie obecności O(n) w IEnumerable<T>.

Jak naprawić naruszenia

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

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 dany kod nie jest krytyczny 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ż