Resolver erros e avisos para declarações de registro

O compilador C# gera erros e avisos quando você usa tipos de registro incorretos. Os tipos de registro fornecem membros internos que implementam a igualdade baseada em valor. Esses diagnósticos ajudam você a seguir as regras para declarar e usar tipos de registro.

  • CS8851: 'type' define 'Equals' mas não 'GetHashCode'
  • CS8857: O receptor de uma with expressão deve ter um tipo não nulo.
  • CS8858: O tipo de receptor 'type' não é um tipo de registro válido e não é um tipo struct.
  • CS8859: os membros chamados 'Clone' não são permitidos em registros.
  • CS8860: tipos e aliases não devem ser chamados de "registro".
  • CS8864: os registros só podem herdar do objeto ou de outro registro.
  • CS8865: somente registros podem herdar de registros.
  • CS8866: o membro de registro 'member' deve ser uma propriedade de instância legível ou um campo do tipo 'type' para corresponder ao parâmetro posicional 'parameter'.
  • CS8869: 'member' não substitui o método esperado de 'object'.
  • CS8870: 'member' não pode ser selado porque o registro que o contém não está selado.
  • CS8871: 'member' não substitui o método esperado de 'type'.
  • CS8872: 'member' deve permitir sobrescrita porque o registro que o contém não é selado.
  • CS8873: o membro de registro 'member' deve ser público.
  • CS8874: o membro de registro 'member' deve retornar 'type'.
  • CS8875: o membro de registro 'member' deve ser protegido.
  • CS8876: 'member' não substitui a propriedade esperada de 'type'.
  • CS8877: o membro de registro 'member' não pode ser estático.
  • CS8879: o membro do registro 'member' deve ser privado.
  • CS8906: a propriedade de contrato de igualdade do registro 'member' deve ter um acessador get.
  • CS8908: O tipo 'type' pode não ser usado para um campo de um registro.
  • CS8913: o membro posicional 'member' encontrado correspondente a este parâmetro está oculto.

Além disso, este artigo aborda o seguinte aviso:

  • CS8907: o parâmetro 'name' não foi lido. Você esqueceu de usá-la para inicializar a propriedade com esse nome?

Assinaturas de membro sintetizadas

  • CS8869: 'member' não substitui o método esperado de 'object'.
  • CS8870: 'member' não pode ser selado porque o registro que o contém não está selado.
  • CS8871: 'member' não substitui o método esperado de 'type'.
  • CS8872: 'member' deve permitir sobrescrita porque o registro que o contém não é selado.
  • CS8873: o membro do registro 'member' deve ser público.
  • CS8874: o membro do registro 'member' deve retornar 'type'.
  • CS8875: o membro 'member' do registro deve ser protegido.
  • CS8876: 'member' não substitui a propriedade esperada de 'type'.
  • CS8877: o membro 'member' do registro não pode ser estático.
  • CS8879: o membro 'member' do registro deve ser privado.
  • CS8906: a propriedade 'member' do contrato de igualdade do registro deve ter um acessador get.

Quando você declarar explicitamente um membro que o compilador, de outra forma, sintetizaria para um tipo de registro, sua declaração deve corresponder a assinatura, acessibilidade e modificadores esperados. Para obter as regras completas, consulte a especificação de registros na especificação da linguagem C#.

Para corrigir esses erros, aplique as seguintes alterações aos seus membros de registro declarados explicitamente:

  • Altere a acessibilidade do método Equals, GetHashCode, ToString, o método de desconstrução, e a propriedade EqualityContract ou os operadores op_Equality e op_Inequality para public. O compilador exige que esses membros sejam acessíveis publicamente para que a igualdade baseada em valor funcione corretamente em todos os contextos de chamada (CS8873).
  • Altere a acessibilidade do PrintMembers método para protected quando você o declarar em uma classe de registro não lacrada. O método deve ser protected porque os registros derivados o substituem para incluir suas próprias propriedades na saída formatada (CS8875).
  • Altere a acessibilidade do método PrintMembers para private quando você o declarar em uma classe de registro selada ou em um registro struct. Como nenhum tipo derivado pode existir, o método não precisa ser acessível fora do tipo (CS8879).
  • Remova o modificador static de qualquer membro sintetizado que tenha sido declarado explicitamente. Os membros sintetizados operam em instâncias de registro específicas para implementar comportamentos como comparação de igualdade, formatação e cópia, portanto, eles devem ser membros da instância (CS8877).
  • Altere o tipo de retorno do membro para corresponder ao tipo esperado pelo compilador. Por exemplo, a EqualityContract propriedade deve retornar System.Typee o Equals método deve retornar bool. O compilador depende desses tipos de retorno exatos para gerar código correto para igualdade e outros comportamentos sintetizados (CS8874).
  • Remova o sealed modificador de qualquer membro sintetizado declarado explicitamente em um registro não selado. Os registros derivados devem ser capazes de substituir esses membros para fornecer sua própria lógica de igualdade e formatação baseada em valor (CS8870).
  • Declare membros sintetizados fornecidos explicitamente como virtual ou override em um registro não lacrado. O compilador requer que esses membros permitam a substituição para que os registros derivados na hierarquia de herança possam personalizar seu comportamento (CS8872).
  • Certifique-se de que o membro declarado explicitamente sobrescreva o método esperado de object ou do tipo de registro base. Por exemplo, o Equals método deve substituir object.Equalse GetHashCode deve substituir object.GetHashCode. O compilador verifica se esses membros participam da cadeia de substituição correta para que a igualdade baseada em valor e outros comportamentos sintetizados funcionem corretamente na hierarquia de tipos (CS8869, CS8871).
  • Verifique se a sua propriedade EqualityContract explicitamente declarada substitui a propriedade do registro de base EqualityContract. O compilador depende da cadeia de sobrescrita para o contrato de igualdade para distinguir os tipos de registro em tempo de execução dentro da hierarquia de herança (CS8876).
  • Adicione um acessador get à propriedade EqualityContract. O compilador lê o contrato de igualdade em tempo de execução para determinar se duas instâncias de registro são do mesmo tipo, portanto, a propriedade deve ser legível (CS8906).

Membros posicionais

  • CS8866: o membro de registro 'member' deve ser uma propriedade de instância legível ou um campo do tipo 'type' para corresponder ao parâmetro posicional 'parameter'.
  • CS8907: o parâmetro 'name' não foi lido. Você esqueceu de usá-la para inicializar a propriedade com esse nome?
  • CS8908: O tipo 'type' pode não ser usado para um campo de um registro.
  • CS8913: o membro posicional 'member' encontrado correspondente a este parâmetro está oculto.

Quando você declara um registro posicional, o compilador sintetiza propriedades que correspondem a cada parâmetro posicional. Esses diagnósticos indicam que suas declarações explícitas entram em conflito com essas propriedades sintetizadas. Para obter as regras completas, consulte a especificação de registros na especificação da linguagem C#.

Para corrigir esses erros, aplique as seguintes alterações às declarações de registro posicional:

  • Altere qualquer membro declarado explicitamente que corresponda a um parâmetro posicional para que ele seja uma propriedade ou campo de instância legível com o mesmo tipo que o parâmetro. O compilador precisa que o membro seja legível e compatível com o tipo para que o método sintetizado Deconstruct e a correspondência de padrões posicionais possam acessar o valor corretamente (CS8866).
  • Verifique se cada parâmetro posicional inicializa sua propriedade correspondente no corpo do construtor quando você fornece um construtor explícito. O compilador gera um aviso quando um parâmetro não é usado porque normalmente indica um erro de digitação ou uma incompatibilidade entre o nome do parâmetro e o nome da propriedade, o que deixaria a propriedade não inicializada (CS8907).
  • Altere o tipo de um campo declarado em um registro para um tipo válido nesse contexto. Determinados tipos, como Span<T> ou outros ref struct tipos, não podem ser usados como campos em um registro porque os tipos de registro exigem que todos os campos sejam compatíveis com a alocação de heap e a igualdade baseada em valor (CS8908).
  • Remova o modificador new de um membro em um registro que, derivado, oculta um membro posicional do registro base. Quando um membro posicional está oculto, o compilador não pode corresponder o parâmetro posicional à sua propriedade correspondente, o que interrompe o método sintetizado Deconstruct e a correspondência de padrões posicionais (CS8913).

Membros de igualdade

  • CS8851: 'type' define 'Equals' mas não 'GetHashCode'
  • CS8857: O receptor de uma with expressão deve ter um tipo não nulo.
  • CS8858: O tipo de receptor 'type' não é um tipo de registro válido e não é um tipo de estrutura.

Os tipos de registro fornecem igualdade interna baseada em valor. Esses diagnósticos surgem quando suas declarações entram em conflito com o contrato de igualdade. Para obter as regras completas sobre igualdade, consulte comparações de igualdade.

Para corrigir esses erros, aplique as seguintes alterações:

  • Adicionar um método GetHashCode sempre que definir um método Equals. O contrato de igualdade requer que os objetos considerados iguais produzam o mesmo código hash, de modo que o compilador impõe que esses dois métodos sejam sempre definidos juntos (CS8851).
  • Altere o receptor de uma expressão with para que seja um tipo de registro ou um tipo de struct. A with expressão cria uma cópia modificada usando o record construtor de cópia ou a semântica de cópia de valor para struct tipos (CS8858).
  • Certifique-se de que o receptor de uma expressão with tenha um tipo não vazio. A expressão with produz uma nova cópia do receptor, portanto, o receptor deve ser avaliado para um valor que possa ser copiado (CS8857).

Herança de registro

  • CS8864: Os registros só podem herdar do objeto ou de outro registro
  • CS8865: Somente registros podem herdar de outros registros.

Os tipos de classe de registro seguem regras de herança específicas. Para obter as regras completas, consulte a especificação de registros na especificação da linguagem C#.

Para corrigir esses erros, aplique as seguintes alterações:

  • Altere o tipo base de uma classe de registro para que ela herde de object ou de outra classe de registro. Os tipos de registro dependem de membros sintetizados pelo compilador para igualdade e cópia que são compatíveis apenas com outros tipos de registro, portanto, o compilador não permite que um registro herde de uma classe não registro (CS8864).
  • Altere uma classe não registrada que herda de uma classe de registro para que seja declarada como uma classe de registro. Como os tipos de registro sintetizam a igualdade, a clonagem e outros membros que dependem de uma cadeia de herança consistente, o compilador requer que todos os tipos na hierarquia sejam uma classe de registro (CS8865). Os tipos de struct de registro não podem participar de hierarquias de herança além da implementação de interfaces.

Nomes de membro reservados

  • CS8859: os membros chamados 'Clone' não são permitidos em registros.
  • CS8860: tipos e aliases não devem ser nomeados como "record".

O compilador reserva determinados nomes para uso com tipos de registro. Para obter as regras completas, consulte a especificação de registros na especificação da linguagem C#.

Para corrigir esses erros, aplique as seguintes alterações:

  • Renomeie qualquer membro chamado Clone em um tipo de registro para um nome diferente. O compilador utiliza Clone internamente para implementar a semântica de cópia em expressões with, e, ao declarar seu próprio membro Clone, há um conflito com a implementação sintetizada (CS8859).
  • Renomeie qualquer tipo ou alias nomeado record para um nome diferente. Como record é uma palavra-chave contextual usada para declarar tipos de registro, nomear um tipo ou alias record cria ambiguidade que pode confundir o compilador e os desenvolvedores que leem o código (CS8860).