Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
| Propriedade | valor |
|---|---|
| ID da regra | CA1841 |
| Título | Prefira métodos que o Dicionário contém |
| Categoria | Desempenho |
| A correção causa interrupção ou não | Ininterrupto |
| Habilitado por padrão no .NET 10 | Como sugestão |
| Línguas aplicáveis | C# e Visual Basic |
Motivo
Esta regra localiza chamadas para um método Contains na coleção Keys ou Values de um IDictionary<TKey,TValue>, que podem ser substituídas por uma chamada para um método ContainsKey ou ContainsValue no próprio dicionário.
Descrição da regra
Chamar Contains na coleção Keys ou Values pode muitas vezes ser mais caro do que chamar ContainsKey ou ContainsValue no dicionário em si:
- Muitas implementações de dicionário instanciam preguiçosamente as coleções de chaves e valores, o que significa que o acesso às coleções
KeysouValuespode resultar em alocações extras. - Você pode acabar chamando um método de extensão em IEnumerable<T> se a coleção de chaves ou de valores usar a implementação de interface explícita para ocultar métodos em ICollection<T>. Isso pode levar a um desempenho reduzido, especialmente ao acessar a coleção de chaves. A maioria das implementações de dicionário são capazes de fornecer uma verificação de contenção O(1) rápida para chaves, enquanto o método de extensão em
Containsgeralmente faz uma verificação de contenção O(n) lentaIEnumerable<T>.
Como corrigir violações
Para corrigir violações, substitua chamadas para dictionary.Keys.Contains ou dictionary.Values.Contains por chamadas para dictionary.ContainsKey ou dictionary.ContainsValue, respectivamente.
O trecho de código a seguir mostra exemplos de violações e como corrigi-las.
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
Quando suprimir avisos
É seguro suprimir avisos dessa regra se o código em questão não for crítico para o desempenho.
Suprimir um aviso
Se você quiser apenas suprimir uma única violação, adicione diretivas de pré-processador ao seu arquivo de origem para desativar e, em seguida, reativar a regra.
#pragma warning disable CA1841
// The code that's violating the rule is on this line.
#pragma warning restore CA1841
Para desabilitar a regra de um arquivo, pasta ou projeto, defina sua gravidade como none no arquivo de configuração.
[*.{cs,vb}]
dotnet_diagnostic.CA1841.severity = none
Para obter mais informações, consulte Como suprimir avisos de análise de código.