Condividi tramite


CA1833: usare AsSpan o AsMemory invece di indicizzatori basati su intervallo per ottenere la parte Span o Memory di una matrice

Proprietà valore
ID regola CA1833
Title Usare AsSpan o AsMemory invece di indicizzatori basati su Range per ottenere la parte Span o Memory di una matrice
Categoria Prestazioni
La correzione causa un'interruzione o meno Non rompente
Abilitato per impostazione predefinita in .NET 10 Come suggerimento
Linguaggi applicabili C# e Visual Basic

Causa

Quando si usa un indicizzatore di intervallo in una matrice e si assegna in modo implicito il valore a Span<T> o Memory<T>.

Descrizione regola

L'indicizzatore di intervalli in un Span<T> oggetto è un'operazione senza copia Slice. Tuttavia, per l'indicizzatore di intervalli in una matrice, il metodo GetSubArray verrà usato invece di Slice, che produce una copia della parte richiesta della matrice. Questa copia in genere non è necessaria quando viene usata in modo implicito come valore di Span<T> o di Memory<T>. Se una copia non è prevista, usare il AsSpan metodo o AsMemory per evitare la copia non necessaria. Se si intende copiare, assegnare la copia prima a una variabile locale o aggiungere un cast esplicito. L'analizzatore segnala solo quando viene usato un cast implicito sul risultato dell'operazione dell'indicizzatore di intervalli.

Rileva

Conversioni implicite:

  • Span<SomeT> slice = arr[a..b];
  • Memory<SomeT> slice = arr[a..b];

Non rileva

Conversioni esplicite:

  • Span<SomeT> slice = (Span<SomeT>)arr[a..b];
  • Memory<SomeT> slice = (Memory<SomeT>)arr[a..b];

Come correggere le violazioni

Per correggere una violazione di questa regola, utilizzare il AsSpan metodo di estensione o AsMemory per evitare di creare copie di dati non necessarie.

class C
{
    public void TestMethod(byte[] arr)
    {
        // The violation occurs for both statements below
        Span<byte> tmp2 = arr[0..5];
        Memory<byte> tmp4 = arr[5..10];
        ...
    }
}
class C
{
    public void TestMethod(byte[] arr)
    {
        // The violations fixed with AsSpan or AsMemory accordingly
        Span<byte> tmp2 = arr.AsSpan()[0..5];
        Memory<byte> tmp4 = arr.AsMemory()[5..10];
        ...
    }
}

Suggerimento

Una correzione del codice è disponibile per questa regola in Visual Studio. Per usarlo, posizionare il cursore sulla violazione e premere CTRL+. (punto). Scegliere Usa AsMemory anziché l'indicizzatore basato su intervallo in una matrice dall'elenco di opzioni presentate.

Correzione del codice per CA1833- Usare AsSpan o AsMemory anziché gli indicizzatori basati su intervallo per ottenere la parte Span o Memory di una matrice

È anche possibile evitare questo avviso aggiungendo un cast esplicito.

class C
{
    public void TestMethod(byte[] arr)
    {
        // The violation occurs
        Span<byte> tmp1 = arr[0..5];
        Memory<byte> tmp2 = arr[5..10];
        ...
    }
}
class C
{
    public void TestMethod(byte[] arr)
    {
        // The violation fixed with explicit casting
        Span<byte> tmp1 = (Span<byte>)arr[0..5];
        Memory<byte> tmp2 = (Memory<byte>)arr[5..10];
        ...
    }
}

Quando eliminare gli avvisi

È possibile eliminare una violazione di questa regola se è prevista la creazione di una copia.

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 CA1833
// The code that's violating the rule is on this line.
#pragma warning restore CA1833

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.CA1833.severity = none

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

Vedi anche