Compartilhar via


Resolver erros e avisos com declarações de matriz embutidas

Este artigo aborda os seguintes erros e avisos do compilador:

  • CS9164: Não é possível converter a expressão em Span<T> porque ela não é uma variável atribuível
  • CS9165: Não é possível converter a expressão em ReadOnlySpan<T> porque ela pode não ser passada ou retornada por referência
  • CS9166: O índice está fora dos limites da matriz embutida
  • CS9167: O comprimento da matriz embutida deve ser maior que 0.
  • CS9168: O struct de matriz embutida não deve ter um layout explícito.
  • CS9169: O struct de matriz embutida deve declarar apenas um campo de instância que não pode ser um campo ref.
  • CS9172: Elementos de um tipo de matriz embutida só podem ser acessados com um único argumento implicitamente conversível para int, System.Index ou System.Range.
  • CS9173: Um acesso à matriz embutida não pode ter um especificador de argumento nomeado
  • CS9180: O campo de elemento de matriz embutido não pode ser declarado como necessário, somente leitura, volátil ou como um buffer de tamanho fixo.
  • CS9181: O indexador de matriz embutido não será usado para expressão de acesso ao elemento.
  • CS9182: O método 'Slice' da matriz embutida não será usado para a expressão de acesso ao elemento.
  • CS9183: O operador de conversão de matriz embutida não será usado para conversão da expressão do tipo declarativo.
  • CS9184: O recurso de linguagem 'Matrizes embutidas' não é suportado para tipos de matriz embutida com campo de elemento que é um campo 'ref' ou tem um tipo que não é válido como um argumento de tipo.
  • CS9189: A instrução foreach em uma matriz embutida de tipo não é suportada
  • CS9259: O atributo System.Runtime.CompilerServices.InlineArrayAttribute não pode ser aplicado a uma estrutura de registro.

Declaração de matriz embutida

Você declara matrizes embutidas como um tipo struct com um único campo e um atributo que especifica o comprimento da matriz. O compilador gera os seguintes erros para declarações de matriz embutida inválidas:

  • CS9167: O comprimento da matriz embutida deve ser maior que 0.
  • CS9168: O struct de matriz embutida não deve ter um layout explícito.
  • CS9169: O struct de matriz embutida deve declarar apenas um campo de instância que não pode ser um campo ref.
  • CS9180: O campo de elemento de matriz embutido não pode ser declarado como necessário, somente leitura, volátil ou como um buffer de tamanho fixo.
  • CS9184: O recurso de linguagem 'Matrizes embutidas' não é suportado para tipos de matriz embutida com campo de elemento que é um campo 'ref' ou tem um tipo que não é válido como um argumento de tipo.
  • CS9259: O atributo System.Runtime.CompilerServices.InlineArrayAttribute não pode ser aplicado a uma estrutura de registro.

Para corrigir essas matrizes, verifique se o seguinte é verdadeiro:

  • O argumento para o System.Runtime.CompilerServices.InlineArrayAttribute é um inteiro positivo.
  • A codificação struct não especifica nenhum layout explícito.
  • A codificação struct tem um único campo de instância e esse campo de instância não é um campo ref.
  • O campo de instância única não é um buffer de tamanho fixo.
  • O campo de instância única não inclui os modificadores required, volatile ou readonly.
  • Remova o record modificador da declaração de matriz embutida.

Acesso a elemento

Você acessa elementos de uma matriz embutida da mesma forma que qualquer matriz. O compilador emite os seguintes erros de acesso incorreto ao elemento:

  • CS9166: O índice está fora dos limites da matriz embutida
  • CS9172: Elementos de um tipo de matriz embutida só podem ser acessados com um único argumento implicitamente conversível para int, System.Index ou System.Range.
  • CS9173: Um acesso à matriz embutida não pode ter um especificador de argumento nomeado
  • CS9189: A instrução foreach em uma matriz embutida de tipo não é suportada

Além disso, o compilador emite o seguinte aviso quando você declara um indexador:

  • CS9181: O indexador de matriz embutido não será usado para expressão de acesso ao elemento.

O código gerado para um buffer embutido acessa a memória do buffer diretamente, ignorando quaisquer indexadores declarados. Matrizes embutidas não podem ser usadas com a instrução foreach.

O argumento para o indexador deve ser:

  • Um desses três tipos: int, um System.Index ou um System.Range.
  • Não pode ser um argumento nomeado. O compilador gera o acessador de elemento. O parâmetro não tem um nome, portanto, você não pode usar argumentos nomeados.
  • Estar incluído nos limites da matriz. Como todas as matrizes .NET, o acesso de elemento de matriz embutida é verificado com limites. O índice deve estar dentro dos limites da matriz embutida.

Conversões em Span

Geralmente, você usa System.Span<T> ou System.ReadOnlySpan<T> para trabalhar com matrizes embutidas. O compilador gera os seguintes erros para conversões inválidas:

  • CS9164: Não é possível converter a expressão em Span<T> porque ela não é uma variável atribuível
  • CS9165: Não é possível converter a expressão em ReadOnlySpan<T> porque ela pode não ser passada ou retornada por referência

O compilador gera código que acessa diretamente a memória de um buffer embutido. Portanto, alguns membros nunca são chamados. O compilador gera os seguintes avisos se você escrever um dos membros que nunca são chamados:

  • CS9182: O método 'Slice' da matriz embutida não será usado para a expressão de acesso ao elemento.
  • CS9183: O operador de conversão de matriz embutida não será usado para conversão da expressão do tipo declarativo.

Uma matriz embutida pode ser convertida implicitamente em um Span<T> ou ReadOnlySpan<T> para passar uma matriz embutida para métodos. O compilador impõe restrições a essas conversões:

  • A matriz embutida deve ser gravável para converter uma matriz embutida em um Span<T>. Se a matriz for somente leitura, você não poderá convertê-la em um gravável Span<T>. Você pode usar ReadOnlySpan<T> em vez dela.
  • O contexto seguro da matriz embutida deve ser pelo menos tão amplo quanto o contexto seguro do Span<T> ou ReadOnlySpan<T> para que a conversão seja bem-sucedida. Você deve limitar o contexto do intervalo ou expandir o escopo da matriz embutida.

Além disso, o compilador nunca gera chamadas para um método Slice em um buffer embutido. Operadores de conversão para converter um buffer embutido em um Span ou ReadOnlySpan não são chamados. O compilador gera código para criar um System.Span<T> ou System.ReadOnlySpan<T> diretamente do buffer de memória.