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 8 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 o Values 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.

Vea también