CA1841: предпочтение словарных методов Contains
Свойство | Значение |
---|---|
Идентификатор правила | CA1841 |
Заголовок | Предпочитать словарь содержит методы |
Категория | Производительность |
Исправление является критическим или не критическим | Не критическое |
Включен по умолчанию в .NET 8 | Как предложение |
Причина
Это правило обнаруживает вызовы метода 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
Дополнительные сведения см. в разделе Практическое руководство. Скрытие предупреждений анализа кода.