Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
| 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
Keysdostępu do kolekcji lubValuesmoż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
Containsmetoda 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.