Compartilhar via


Resolver erros e avisos em declarações de construtor

Este artigo aborda os seguintes erros do compilador:

  • CS0514: o construtor estático não pode ter uma chamada explícita ao construtor 'this' ou 'base'.
  • CS0515: modificadores de acesso não são permitidos em construtores estáticos.
  • CS0516: o construtor "constructor" não pode chamar a si mesmo.
  • CS0517: 'class' não tem classe base e não pode chamar um construtor base.
  • CS0522: structs não podem chamar construtores de classe base.
  • CS0526: Interfaces não podem conter construtores.
  • CS0568: Structs não podem conter construtores explícitos sem parâmetros.
  • CS0710: classes estáticas não podem ter construtores de instância.
  • CS0768: O construtor não pode chamar a si mesmo por meio de outro construtor.
  • CS8054: Enums não podem conter construtores explícitos sem parâmetros.
  • CS8091: não pode ser externo nem ter um inicializador de construtor.
  • CS8861: lista de argumentos inesperados.
  • CS8862: Um construtor declarado em um tipo com uma lista de parâmetros deve ter o inicializador do construtor 'this'.
  • CS8358: Não é possível usar o construtor de atributos porque ele tem parâmetros 'in'.
  • CS8867: Nenhum construtor de cópia acessível encontrado no tipo base '{0}'.
  • CS8868: Um construtor de cópia em um registro deve chamar um construtor de cópia da base ou um construtor de objeto sem parâmetros se o registro herdar do objeto.
  • CS8878: Um construtor de cópia '{0}' deve ser público ou protegido porque o registro não está lacrado.
  • CS8910: O construtor primário entra em conflito com o construtor de cópia sintetizado.
  • CS8958: O construtor de struct sem parâmetros deve ser "público".
  • CS8982: Um construtor declarado em um 'struct' com lista de parâmetros deve ter um inicializador 'this' que chame o construtor primário ou um construtor declarado explicitamente.
  • CS8983: Um 'struct' com inicializadores de campo deve incluir um construtor declarado explicitamente.
  • CS9105: Não é possível usar o parâmetro de construtor primário neste contexto.
  • CS9106: O identificador é ambíguo entre tipo e parâmetro nesse contexto.
  • CS9108: Não é possível usar um parâmetro do tipo semelhante a referência dentro de um método anônimo, expressão lambda, expressão de consulta ou função local.
  • CS9109: Não é possível usar ref, outou in parâmetro de construtor primário dentro de um membro da instância.
  • CS9110: Não é possível usar o parâmetro de construtor primário que tenha o tipo ref-like dentro de um membro de instância.
  • CS9111: métodos anônimos, expressões lambda, expressões de consulta e funções locais dentro de um membro de instância de um struct não podem acessar o parâmetro do construtor primário.
  • CS9112: métodos anônimos, expressões lambda, expressões de consulta e funções locais dentro de um struct não podem acessar o parâmetro de construtor primário também usado dentro de um membro de instância.
  • CS9114: Um parâmetro de construtor primário de um tipo somente leitura não pode receber uma atribuição (exceto no setter somente inicialização do tipo ou em um inicializador de variável).
  • CS9115: Um parâmetro de construtor primário de um tipo somente leitura não pode ser retornado por referência gravável.
  • CS9116: um parâmetro de construtor primário de um tipo somente leitura não pode ser usado como um valor de referência ou saída (exceto no setter somente inicialização do tipo ou em um inicializador de variável).
  • CS9117: Membros de um parâmetro de construtor primário de um tipo somente leitura não podem ser modificados (exceto no setter somente inicialização do tipo ou em um inicializador de variável).
  • CS9118: Membros do parâmetro de construtor primário de um tipo somente leitura não podem ser retornados por referência gravável.
  • CS9119: Membros do parâmetro de construtor primário de um tipo somente leitura não podem ser usados como valor ref ou out (exceto no setter somente inicialização do tipo ou em um inicializador de variável).
  • CS9120: Não é possível retornar o parâmetro do construtor primário por referência.
  • CS9121: O parâmetro de construtor primário de struct do tipo causa um ciclo no layout do struct.
  • CS9122: lista de parâmetros inesperados.
  • CS9136: não é possível usar o parâmetro de construtor primário do tipo dentro de um membro de instância.

Além disso, os seguintes avisos são abordados neste artigo:

  • CS0824: O construtor 'name' está marcado como externo.
  • CS9107: o parâmetro é capturado no estado do tipo delimitador e o valor dele também é transmitido para o construtor base. O valor também pode ser capturado pela classe base.
  • CS9113: o parâmetro não foi lido.
  • CS9124: Parameter é capturado no estado do tipo delimitante e seu valor também é usado para inicializar um campo, uma propriedade ou um evento.
  • CS9179: o parâmetro do construtor primário é sombreado por um membro da base

Construtores estáticos

  • CS0514: o construtor estático não pode ter uma chamada explícita ao construtor 'this' ou 'base'.
  • CS0515: modificadores de acesso não são permitidos em construtores estáticos.

Você pode escrever no máximo um construtor estático para um tipo. A declaração de um construtor estático precisa obedecer às seguintes regras:

  • O construtor estático tem o modificador static, mas nenhum outro modificador, como public, protected, privateou internal.
  • O construtor estático deve ser um construtor sem parâmetros.
  • O construtor estático não pode chamar base() nem this(). Se a classe base incluir um construtor estático, o runtime o chamará automaticamente.

Declaração do construtor

  • CS0526: Interfaces não podem conter construtores.
  • CS0710: classes estáticas não podem ter construtores de instância.
  • CS8054: Enums não podem conter construtores explícitos sem parâmetros.
  • CS8358: Não é possível usar o construtor de atributos porque ele tem parâmetros 'in'.
  • CS8091: um construtor não pode ser externo nem ter um inicializador de construtor.

Construtores são permitidos somente nos tipos class e struct, incluindo os tipos record class e record struct. Você não pode defini-los em tipos enum ou interface. Além disso, tipos de classe de atributo não podem declarar parâmetros in. Em vez disso, passe parâmetros por valor.

Você pode declarar construtores extern; no entanto, não é possível usar chamadas de construtores base() ou this() para invocar outro construtor a partir de um construtor declarado como extern.

Além disso, os seguintes avisos podem ser gerados para declarações de construtor:

  • CS0824: o construtor está marcado como externo.

Quando um construtor é marcado extern, o compilador não pode garantir que o construtor exista. Portanto, o compilador gera esse aviso.

Construtores em tipos de struct

  • CS0568: Structs não podem conter construtores explícitos sem parâmetros.
  • CS8958: O construtor de struct sem parâmetros deve ser "público".
  • CS8982: Um construtor declarado em um 'struct' com lista de parâmetros deve ter um inicializador 'this' que chame o construtor primário ou um construtor declarado explicitamente.
  • CS8983: Um 'struct' com inicializadores de campo deve incluir um construtor declarado explicitamente.

Os recursos recentes no C# removem restrições anteriores a tipos de struct. CS0568 é gerado quando você declara um construtor de instância sem parâmetros em versões mais antigas do C#. Você pode declarar um construtor de instância sem parâmetros explícito em versões mais recentes do C#. Esse construtor sem parâmetros explícito deve ser public. Se o seu struct declarar inicializadores de campo, você também deverá declarar um construtor de instância explícito. Esse construtor pode ser um construtor sem parâmetros com um corpo vazio.

Quando um tipo struct declara um construtor primário, incluindo tipos record struct, todos os outros construtores de instância, exceto um construtor sem parâmetros, devem chamar o construtor primário ou outro construtor declarado explicitamente usando this().

Chamadas de construtor com base e this

  • CS0516: o construtor não pode chamar a si mesmo.
  • CS0517: Class não tem classe base e não pode chamar um construtor base.
  • CS0522: structs não podem chamar construtores de classe base.
  • CS0768: O construtor não pode chamar a si mesmo por meio de outro construtor.

Você pode usar base() e this() para que um construtor chame outro no mesmo tipo ou no tipo base. Chamar construtores pode minimizar a duplicação da lógica de construtor. Você deve seguir estas regras ao chamar outro construtor usando this() ou base():

  • Um construtor não pode chamar a si mesmo direta ou indiretamente por meio de outro construtor. Por exemplo, o código a seguir é ilegal:

    public class C
    {
      public C() : this() // Error!
      {
      }
    }
    
    public class C2
    {
      public class C2() : this(10) {}
    
      public class C2(int capacity) : this() 
      {
          _capacity = capacity;
      }
    
      private int _capacity;
    }
    ``
    
    
  • Tipos de struct não podem chamar base(). Nem System.Objectpode.

Registros e construtores de cópia

  • CS8867: Nenhum construtor de cópia acessível foi encontrado no tipo base.
  • CS8868: Um construtor de cópia em um registro precisa chamar um construtor de cópia da base, ou um construtor de objeto sem parâmetros se o registro herdar do objeto.
  • CS8878: Um construtor de cópia precisa ser público ou protegido porque o registro não está selado.
  • CS8910: O construtor primário entra em conflito com o construtor de cópia sintetizado.

Adicionar o modificador record a um tipo struct ou class cria um registro. Os registros incluem um construtor de cópia sintetizado pelo compilador. Você pode escrever um construtor de cópia explícito por conta própria, mas ele deve seguir as seguintes regras:

  • Os construtores de cópia devem ser public ou protected, a menos que o tipo seja sealed.
  • Construtores de cópia devem chamar o construtor de cópia base(), a menos que a classe base seja System.Object.
  • Além disso, o tipo base precisa ter um construtor de cópia. record sempre têm um construtor de cópia.

Declaração de construtor primário

O compilador emite os seguintes erros quando um construtor primário viola uma ou mais regras em construtores primários para classes e structs:

  • CS8861: Lista de argumentos inesperados.
  • CS8862: Um construtor declarado em um tipo com lista de parâmetros precisa ter o inicializador de construtor 'this'.
  • CS9105: Não é possível usar o parâmetro de construtor primário neste contexto.
  • CS9106: O identificador é ambíguo entre tipo e parâmetro nesse contexto.
  • CS9108: Não é possível usar parâmetro que tenha tipo ref dentro de um método anônimo, expressão lambda, expressão de consulta ou função local.
  • CS9109: Não é possível usar ref, outou in parâmetro de construtor primário dentro de um membro da instância.
  • CS9110: Não é possível usar o parâmetro de construtor primário que tem um tipo semelhante a ref dentro de um membro de instância.
  • CS9111: métodos anônimos, expressões lambda, expressões de consulta e funções locais dentro de um membro de instância de um struct não podem acessar o parâmetro do construtor primário.
  • CS9112: Métodos anônimos, expressões lambda, expressões de consulta e funções locais dentro de um struct não podem acessar o parâmetro de construtor primário, também usado dentro de um membro de instância.
  • CS9114: Um parâmetro de construtor primário de um tipo somente leitura não pode receber uma atribuição (exceto no setter somente inicialização do tipo ou em um inicializador de variável).
  • CS9115: Um parâmetro de construtor primário de um tipo somente leitura não pode ser retornado por referência gravável.
  • CS9116: um parâmetro de construtor primário de um tipo somente leitura não pode ser usado como um valor ref ou out (exceto no setter somente inicialização do tipo ou em um inicializador de variável).
  • CS9117: Membros de um parâmetro de construtor primário de um tipo somente leitura não podem ser modificados (exceto no setter somente inicialização do tipo ou em um inicializador de variável).
  • CS9118: Membros do parâmetro de construtor primário de um tipo somente leitura não podem ser retornados por referência gravável.
  • CS9119: Membros do parâmetro de construtor primário de um tipo somente leitura não podem ser usados como valor ref ou out (exceto no setter somente inicialização do tipo ou em um inicializador de variável).
  • CS9120: Não é possível retornar o parâmetro de construtor primário por referência.
  • CS9121: O parâmetro de construtor primário de struct do tipo causa um ciclo no layout do struct.
  • CS9122: Lista de parâmetros inesperada.
  • CS9124: O parâmetro é capturado no estado do tipo envolvente e seu valor também é usado para inicializar um campo, uma propriedade ou um evento.
  • CS9136: não é possível usar o parâmetro de construtor primário do tipo dentro de um membro de instância.

Ao usar um construtor primário em uma classe ou struct, cada construtor declarado explicitamente deve chamar o construtor primário usando : this(...) uma lista de argumentos apropriada. Isso garante que o construtor primário seja sempre invocado. Para obter mais informações sobre construtores primários, consulte o artigo sobre construtores de instância no guia de programação.

Os parâmetros do construtor primário estão no escopo no corpo desse tipo. O compilador pode sintetizar um campo que armazena o parâmetro para uso em membros ou em inicializadores de campo. Como um parâmetro de construtor primário pode ser copiado para um campo, as seguintes restrições se aplicam:

  • Construtores primários podem ser declarados em tipos struct e class, mas não em tipos de interface.
  • Os parâmetros do construtor primário não podem ser usados em uma chamada de construtor base(), a menos que sejam parte do construtor primário.
  • Parâmetros de construtor primário do tipo ref struct não podem ser acessados em expressões lambda, expressões de consulta ou funções locais.
  • Se o tipo não for um ref struct, os parâmetros ref struct não poderão ser acessados em membros da instância.
  • Em um tipo ref struct, parâmetros de construtor primário com os modificadores in, ref ou out não podem ser usados em nenhum método de instância ou acessador de propriedade.

Os tipos de struct têm as seguintes restrições extras nos parâmetros de construtor primário:

  • Os parâmetros do construtor primário não podem ser capturados em expressões lambda, expressões de consulta ou funções locais.
  • Parâmetros do construtor primário não podem ser retornados por referência (retornoref ou retorno readonly ref).

Os tipos de struct somente leitura têm as seguintes restrições extras nos parâmetros de construtor primário:

  • Os parâmetros do construtor primário e seus membros não podem ser reatribuídos em um struct readonly.
  • Parâmetros de construtor primário e seus membros não podem ser retornados ref em um struct readonly.
  • Parâmetros de construtor primário e seus membros não podem ser argumentos ref ou out para qualquer método.

Em todos esses casos, as restrições em parâmetros de construtor primário são consistentes com restrições em campos de dados nesses tipos. As restrições ocorrem porque um parâmetro de construtor primário pode ser transformado em um campo sintetizado no tipo. Portanto, os parâmetros do construtor primário devem seguir as regras que se aplicam a esse campo sintetizado.

Um construtor primário derivado chama o construtor primário base fornecendo os parâmetros para o construtor base. Você deve usar os nomes de parâmetro da declaração de construtor derivada.

Os avisos fornecem diretrizes sobre os parâmetros de construtor primário capturados ou sombreados.

  • CS9107: o parâmetro é capturado no estado do tipo delimitador e o valor dele também é transmitido para o construtor base. O valor também pode ser capturado pela classe base. Esse aviso indica que o código pode receber duas cópias de um parâmetro de construtor primário. Como o parâmetro é passado para a classe base, a classe base provavelmente o usa. Como a classe derivada a acessa, ela pode ter uma segunda cópia do mesmo parâmetro. Esse armazenamento extra pode não ser pretendido.
  • CS9113: o parâmetro não foi lido. Esse aviso indica que a classe nunca referencia o construtor primário, nem mesmo para transmiti-lo para o construtor primário base. Provavelmente não é necessário.
  • CS9124: o parâmetro é capturado no estado do tipo delimitador e o valor dele também é usado para inicializar um campo, uma propriedade ou um evento. Esse aviso indica que o parâmetro de construtor de um tipo aninhado também é capturado pelo tipo delimitador. O parâmetro provavelmente é armazenado duas vezes.
  • CS9179: o parâmetro do construtor primário é sombreado por um membro da base