Condividi tramite


CA1841: Prefer Dictionary Contains methods

Proprietà valore
ID regola CA1841
Title Preferisce i metodi Dictionary Contains
Categoria Prestazioni
La correzione causa un'interruzione o meno Non causa un'interruzione
Abilitato per impostazione predefinita in .NET 9 Come suggerimento

Causa

Questa regola individua le chiamate a un Contains metodo nell'insieme Keys o Values di un oggetto IDictionary<TKey,TValue> che può essere sostituito con una chiamata a un ContainsKey metodo o ContainsValue nel dizionario stesso.

Descrizione regola

La chiamata Contains alla Keys raccolta o Values può spesso essere più costosa rispetto alla chiamata ContainsKey o ContainsValue al dizionario stesso:

  • Molte implementazioni del dizionario creano un'istanza differita delle raccolte chiave e valore, il che significa che l'accesso alla Keys raccolta o Values può comportare allocazioni aggiuntive.
  • È possibile chiamare un metodo di estensione se IEnumerable<T> la raccolta chiavi o valori usa l'implementazione esplicita dell'interfaccia per nascondere i metodi in ICollection<T>. Ciò può comportare una riduzione delle prestazioni, soprattutto quando si accede alla raccolta di chiavi. La maggior parte delle implementazioni del dizionario è in grado di fornire un controllo di contenimento rapido di O(1) per le chiavi, mentre il Contains metodo di estensione in IEnumerable<T> genere esegue un controllo di contenimento O(n) lento.

Come correggere le violazioni

Per correggere le violazioni, sostituire rispettivamente le chiamate a dictionary.Keys.Contains o dictionary.Values.Contains con chiamate a dictionary.ContainsKey o dictionary.ContainsValue.

Il frammento di codice seguente mostra esempi di violazioni e come risolverli.

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 eliminare gli avvisi

È possibile eliminare gli avvisi da questa regola se il codice in questione non è critico per le prestazioni.

Eliminare un avviso

Se si vuole eliminare una singola violazione, aggiungere direttive del preprocessore al file di origine per disabilitare e quindi riabilitare la regola.

#pragma warning disable CA1841
// The code that's violating the rule is on this line.
#pragma warning restore CA1841

Per disabilitare la regola per un file, una cartella o un progetto, impostarne la gravità none su nel file di configurazione.

[*.{cs,vb}]
dotnet_diagnostic.CA1841.severity = none

Per altre informazioni, vedere Come eliminare gli avvisi di analisi del codice.

Vedi anche