Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
| Свойство | Значение |
|---|---|
| Идентификатор правила | CA1841 |
| Заголовок | Предпочтительно использовать методы Contains для словарей |
| Категория | Производительность |
| Исправление является критическим или не критическим | неразрывный |
| Включен по умолчанию в .NET 10 | Как предложение |
| Применимые языки | C# и Visual Basic |
Причина
Это правило обнаруживает вызовы метода Contains, выполненные в отношении коллекции Keys или Values объекта IDictionary<TKey,TValue>, которые можно заменить вызовом метода ContainsKey или ContainsValue, непосредственно обращенного к самому словарю.
Описание правила
Вызов Contains для коллекции Keys или Values часто может быть более затратным, чем вызов ContainsKey или ContainsValue для самого словаря.
- Многие реализации словаря откладывают создание коллекций ключей и значений, что означает, что доступ к коллекции
KeysилиValuesможет вызвать дополнительное выделение памяти. - Может даже потребоваться вызов метода расширения для IEnumerable<T>, если коллекция ключей или значений использует явную реализацию интерфейса для скрытия методов в ICollection<T>. Это может снизить производительность, особенно при доступе к коллекции ключей. Большинство реализаций словарей позволяют осуществлять быструю (O(1)) проверку наличия ключей, тогда как метод расширения
Containsдля IEnumerable<T> обычно выполняет лишь медленную проверку наличия (O(n)).
Устранение нарушений
Для устранения нарушений замените вызовы dictionary.Keys.Contains или dictionary.Values.Contains на вызовы dictionary.ContainsKey или dictionary.ContainsValue соответственно.
В следующем фрагменте кода приведены примеры нарушений и способы их устранения.
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
Когда лучше отключить предупреждения
Можно безопасно скрывать предупреждения по этому правилу, если производительность кода, который его нарушает, не несет критической важности.
Отключение предупреждений
Если вы просто хотите отключить одно нарушение, добавьте директивы препроцессора в исходный файл, чтобы отключить и повторно включить правило.
#pragma warning disable CA1841
// The code that's violating the rule is on this line.
#pragma warning restore CA1841
Чтобы отключить правило для файла, папки или проекта, задайте его серьезность none в файле конфигурации.
[*.{cs,vb}]
dotnet_diagnostic.CA1841.severity = none
Дополнительные сведения см. в разделе Практическое руководство. Скрытие предупреждений анализа кода.