CA1833: Usar AsSpan ou AsMemory em vez de indexadores baseados em intervalo para obter a parte Span ou Memory de uma matriz

Property Valor
ID da regra CA1833
Título Usar AsSpan ou AsMemory em vez de indexadores baseados em intervalo para obter a parte Span ou Memory de uma matriz
Categoria Desempenho
Correção interruptiva ou sem interrupção Sem interrupção
Habilitado por padrão no .NET 8 Como sugestão

Causa

Ao usar um indexador de intervalo em uma matriz e atribuir implicitamente o valor a Span<T> ou Memory<T>.

Descrição da regra

O indexador de intervalo em um Span<T> é uma operação Slice sem cópia. Mas para o indexador de intervalo em uma matriz, o método GetSubArray será usado em vez de Slice, que produz uma cópia da parte solicitada da matriz. Essa cópia geralmente é desnecessária quando é usada implicitamente como um valor Span<T> ou Memory<T>. Se uma cópia não for pretendida, use o método AsSpan ou AsMemory para evitar a cópia desnecessária. Se a cópia for pretendida, atribua-a primeiro a uma variável local ou adicione uma conversão explícita. O analisador relatará apenas quando uma conversão implícita for utilizada no resultado da operação do indexador de intervalo.

Detecta

Conversões implícitas:

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

Não detecta

Conversões explícitas:

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

Como corrigir violações

Para corrigir uma violação dessa regra, utilize o método de extensão AsSpan ou AsMemory para evitar a criação de cópias de dados desnecessárias.

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];
        ...
    }
}

Dica

Uma correção de código está disponível para essa regra no Visual Studio. Para usá-la, posicione o cursor sobre a violação e pressione Ctrl+. (ponto). Escolha Usar AsMemory em vez do indexador com base em intervalo em uma matriz na lista de opções apresentada.

Code fix for CA1833 - Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array

Você também pode evitar esse aviso adicionando uma conversão explícita.

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 suprimir avisos

É seguro suprimir uma violação dessa regra se a criação de uma cópia é intencional.

Suprimir um aviso

Para suprimir apenas uma violação, adicione diretivas de pré-processador ao arquivo de origem a fim de desabilitar e, em seguida, reabilitar a regra.

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

Para desabilitar a regra em um arquivo, uma pasta ou um projeto, defina a severidade como none no arquivo de configuração.

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

Para obter mais informações, confira Como suprimir avisos de análise de código.

Confira também