Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
| 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
KeyslubValuesmoż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
Containszazwyczaj 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.