CA1841: Preferencia por los métodos Contains para un diccionario
Propiedad | Value |
---|---|
Identificador de la regla | CA1841 |
Título | Preferir el diccionario Contiene métodos |
Categoría | Rendimiento |
La corrección es problemática o no problemática | Poco problemático |
Habilitado de forma predeterminada en .NET 9 | Como sugerencia |
Causa
Esta regla busca llamadas a un método Contains
en la colección Keys
o Values
de un objeto IDictionary<TKey,TValue> que se podrían reemplazar por una llamada a un método ContainsKey
o ContainsValue
en el propio diccionario.
Descripción de la regla
A menudo, llamar a Contains
en la colección Keys
o Values
puede resultar más costoso que llamar a ContainsKey
o ContainsValue
en el propio diccionario:
- Muchas implementaciones de diccionario crean una instancia de forma diferida de las colecciones de clave y valor, lo que significa que el acceso a la colección
Keys
oValues
puede dar lugar a asignaciones adicionales. - Puede terminar llamando a un método de extensión en IEnumerable<T> si en la colección de claves o valores se usa la implementación de interfaz explícita para ocultar métodos en ICollection<T>. Esto puede reducir el rendimiento, especialmente al acceder a la colección de claves. La mayoría de las implementaciones de diccionario pueden proporcionar una comprobación rápida de contención O(1) de claves, mientras que el método de extensión
Contains
en IEnumerable<T> normalmente realiza una comprobación de contención O(n) lenta.
Cómo corregir infracciones
Para corregir las infracciones, reemplace las llamadas a dictionary.Keys.Contains
o dictionary.Values.Contains
por llamadas a dictionary.ContainsKey
o dictionary.ContainsValue
, respectivamente.
En el fragmento de código siguiente se muestran ejemplos de infracciones y cómo corregirlas.
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
Cuándo suprimir las advertencias
Es seguro suprimir las advertencias de esta regla si el código en cuestión no es crítico para el rendimiento.
Supresión de una advertencia
Si solo quiere suprimir una única infracción, agregue directivas de preprocesador al archivo de origen para deshabilitar y volver a habilitar la regla.
#pragma warning disable CA1841
// The code that's violating the rule is on this line.
#pragma warning restore CA1841
Para deshabilitar la regla de un archivo, una carpeta o un proyecto, establezca su gravedad en none
del archivo de configuración.
[*.{cs,vb}]
dotnet_diagnostic.CA1841.severity = none
Para obtener más información, consulte Procedimiento para suprimir advertencias de análisis de código.