Partilhar via


Resolver erros e avisos para declarações de operadores e sobrecarga

Este artigo aborda os seguintes erros e avisos do compilador:

  • CS0031: Valor constante 'valor' não pode ser convertido num 'tipo'
  • CS0056: Acessibilidade inconsistente: o tipo de retorno 'tipo' é menos acessível do que o operador 'operador'
  • CS0057: Acessibilidade inconsistente: o tipo de parâmetro 'tipo' é menos acessível do que o operador 'operador'
  • CS0215: O tipo de retorno do operador True ou False deve ser bool
  • CS0216: O operador «operador» requer também a definição de um operador correspondente «missing_operator»
  • CS0217: Para ser aplicável como operador de curto-circuito, um operador lógico definido pelo utilizador («operador») deve ter o mesmo tipo de retorno que o tipo dos seus 2 parâmetros.
  • CS0218: O tipo («tipo») deve conter declarações de operador verdadeiro e operador falso
  • CS0220: A operação excede durante a compilação em modo seguro
  • CS0221: Valor constante 'valor' não pode ser convertido num 'tipo' (use a sintaxe 'unchecked' para sobrepor)
  • CS0448: O tipo de retorno para o operador ++ ou -- deve ser o tipo que o contém ou derivado do tipo que o contém
  • CS0463: Avaliação da expressão da constante decimal falhou com erro: 'erro'
  • CS0543: 'enumeração': o valor do enumerador é demasiado grande para caber no seu tipo
  • CS0552: 'rotina de conversão' : conversão definida pelo usuário para/da interface
  • CS0553: 'rotina de conversão' : conversão definida pelo usuário de/para a classe base
  • CS0554: 'rotina de conversão' : conversão definida pelo usuário de/para classe derivada
  • CS0555: O operador definido pelo usuário não pode pegar um objeto do tipo de delimitação e converter em um objeto do tipo de delimitação
  • CS0556: A conversão definida pelo usuário deve ser convertida para ou a partir do tipo envolvente
  • CS0557: Duplicar a conversão definida pelo usuário no tipo
  • CS0558: O operador definido pelo usuário deve ser declarado estático e público
  • CS0559: O tipo de parâmetro para o operador ++ ou -- deve ser o tipo que o contém
  • CS0562: O parâmetro de um operador unário deve ser o tipo que contém
  • CS0563: Um dos parâmetros de um operador binário deve ser o tipo que contém
  • CS0564: O primeiro operando de um operador de turno sobrecarregado deve ter o mesmo tipo que o tipo que o contém, e o tipo do segundo operando deve ser int
  • CS0567: As interfaces não podem conter operadores
  • CS0590: Operadores definidos pelo usuário não podem retornar void
  • CS0594: A constante de ponto flutuante está fora do intervalo do tipo 'tipo'
  • CS0652: A comparação com a constante integral é inútil; a constante está fora do intervalo do tipo 'tipo'
  • CS0659: 'class' sobrepõe Object.Equals(object o) mas não sobrepõe Object.GetHashCode()
  • CS0660: Tipo define operator == ou operator != mas não substitui Object.Equals(object o)
  • CS0661: Tipo define operator == ou operator != mas não substitui Object.GetHashCode()
  • CS0715: Classes estáticas não podem conter operadores definidos pelo usuário
  • CS1021: Constante integral é demasiado grande
  • CS1037: Operador sobrecarregável esperado
  • CS1553: A declaração não é válida; use 'modificador operador <dest-type> (...' em vez disso,
  • CS8930: A implementação explícita de um operador definido pelo utilizador deve ser declarada estática
  • CS8931: A conversão definida pelo utilizador numa interface deve converter para ou a partir de um parâmetro de tipo no tipo de anexo restrito ao tipo de anexo
  • CS8778: Valor constante 'valor' pode transbordar o 'tipo' em tempo de execução (use a sintaxe 'unchecked' para anular)
  • CS8973: A operação pode transbordar em tempo de execução (use a sintaxe 'unchecked' para sobrescrever)
  • CS9023: O operador não pode ser verificado.
  • CS9024: O operador não pode ser inalterável.
  • CS9025: O operador requer que também seja declarada uma versão não verificada correspondente.
  • CS9027: Palavra-chave inesperada 'unchecked'.
  • CS9308: O operador definido pelo usuário deve ser declarado público.
  • CS9310: O tipo de retorno para este operador deve ser nulo.
  • CS9311: O tipo não implementa o membro da interface. O tipo não pode implementar membro porque um deles não é um operador.
  • CS9312: O tipo não pode substituir o membro herdado porque um deles não é um operador.
  • CS9313: O operador de atribuição composto sobrecarregado usa um parâmetro.
  • CS9340: O operador não pode ser aplicado a operandos. É indicado o candidato inaplicável mais próximo.
  • CS9341: O operador não pode ser aplicado ao operando. É indicado o candidato inaplicável mais próximo.
  • CS9342: A resolução do operador é ambígua entre os seguintes membros.

Requisitos de assinatura do operador

  • CS0448: O tipo de retorno para o operador ++ ou -- deve ser o tipo que encapsula ou derivado do tipo que encapsula.
  • CS0559: O tipo de parâmetro para o operador ++ ou -- deve ser o tipo que o contém.
  • CS0562: O parâmetro de um operador unário deve ser o tipo que o contém.
  • CS0563: Um dos parâmetros de um operador binário deve ser o tipo que contém.
  • CS0564: O primeiro operando de um operador de turno sobrecarregado deve ter o mesmo tipo que o tipo que o contém, e o tipo do segundo operando deve ser int.
  • CS0567: As interfaces não podem conter operadores.
  • CS0590: Os operadores definidos pelo usuário não podem retornar void.
  • CS9310: O tipo de retorno para este operador deve ser nulo.
  • CS9340: O operador não pode ser aplicado a operandos. É indicado o candidato inaplicável mais próximo.
  • CS9341: O operador não pode ser aplicado ao operando. É indicado o candidato inaplicável mais próximo.
  • CS9342: A definição do operador é ambígua entre os seguintes membros.

Cada tipo de operador tem parâmetros específicos e requisitos de tipo de retorno definidos pela especificação da linguagem. Para as regras completas sobre quais operadores podem ser sobrecarregados, veja Operador sobrecarregando e Operadores na especificação C#.

  • Altere o tipo de retorno do operador ++ ou -- para o tipo que contém ou para um tipo derivado dele (CS0448). A linguagem exige que os operadores de incremento e decremento devolvam um valor compatível com o tipo que contém para que o resultado possa ser atribuído de volta à mesma variável.
  • Altere o parâmetro dos operadores ++ ou -- para o tipo que os contém (CS0559). Os operadores de incremento e decremento têm de operar em instâncias do seu próprio tipo.
  • Altere o parâmetro de um operador unário para o tipo de contenção (CS0562). Operadores unários devem aceitar um operando do tipo que os declara.
  • Certifique-se de que pelo menos um parâmetro de um operador binário é o tipo de contenção (CS0563). Os operadores binários devem envolver o tipo declarante para que o compilador os possa resolver através desse tipo.
  • Altere o primeiro parâmetro de um operador de deslocamento para o tipo de contenção e o segundo parâmetro para int (CS0564). A linguagem define operadores de deslocamento com uma assinatura específica: o tipo a ser deslocado e uma quantidade inteira de deslocamento.
  • Mover declarações de operador para fora das interfaces e para classes ou structs (CS0567). Declarações de operadores tradicionais (não estáticos e abstratos) não são permitidas em interfaces. Para operadores abstratos estáticos em interfaces, veja Erros de membros abstratos estáticos e virtuais em interfaces.
  • Altere o tipo de retorno do operador para um tipo não nulo (CS0590). A maioria dos operadores definidos pelo utilizador deve devolver um valor. A exceção são os operadores de atribuição composta, que requerem um void tipo de retorno (CS9310).
  • Corrigir os tipos de parâmetros ou adicionar sobrecargas de operadores em falta para que o compilador possa encontrar um operador correspondente para os tipos de operandos usados no local de chamada (CS9340, CS9341). Quando não existe um operador aplicável, o compilador mostra o candidato mais próximo para ajudar a diagnosticar a incompatibilidade.
  • Adicionar casts explícitos no local da chamada, ou fornecer sobrecargas mais específicas para eliminar ambiguidade quando sobrecargas de múltiplos operadores coincidem igualmente bem (CS9342).

Importante

Os requisitos de assinatura para operadores binários estáticos e os operadores de atribuição compostos de instância correspondentes são diferentes. Certifique-se de que a assinatura corresponde à declaração pretendida.

Requisitos em matéria de declaração do operador

  • CS0558: O operador definido pelo usuário deve ser declarado estático e público.
  • CS0715: As classes estáticas não podem conter operadores definidos pelo usuário.
  • CS1037: Operador sobrecarregado esperado.
  • CS1553: Declaração não é válida; use 'modificador operador <dest-type> (...' em vez disso.
  • CS9308: O operador definido pelo usuário deve ser declarado público.

A linguagem requer modificadores e sintaxe específicos para declarações de operadores. Para as regras completas, veja Operadores de sobrecarga e Operadores de conversão definidos pelo utilizador.

  • Adicione ambos os static modificadores e public à declaração do operador (CS0558, CS9308). A linguagem C# exige que todos os operadores definidos pelo utilizador sejam tanto estáticos como públicos, para que sejam acessíveis e chamáveis sem instância.
  • Mover a declaração do operador de uma classe estática para uma classe ou struct não estática (CS0715). As classes estáticas não podem ter instâncias, por isso operadores definidos pelo utilizador — que operam em instâncias do seu tipo contendo — não têm significado em classes estáticas.
  • Substitua o símbolo do operador inválido por um operador válido e sobrecarregável (CS1037). Apenas operadores específicos definidos pela linguagem podem ser sobrecarregados.
  • Corrigir a sintaxe para seguir a forma requerida do operador de conversão: public static implicit operator <dest-type>(<source-type> parameter) ou public static explicit operator <dest-type>(<source-type> parameter) (CS1553). O compilador espera que os operadores de conversão sigam um padrão de declaração específico.

Para erros relacionados com implementações explícitas de interfaces de operadores em interfaces abstratas estáticas, veja Erros estáticos abstratos e membros de interfaces virtuais.

Acessibilidade inconsistente

  • CS0056: Acessibilidade inconsistente: o tipo de retorno 'tipo' é menos acessível do que o operador 'operador'.
  • CS0057: Acessibilidade inconsistente: o tipo de parâmetro «tipo» é menos acessível do que o operador «operador».

Todos os tipos usados na assinatura de um operador público devem ser pelo menos tão acessíveis quanto o próprio operador. Para as regras completas, veja Modificadores de Acesso e Restrições de Acessibilidade na especificação C#.

  • Mude o tipo de retorno para um tipo que seja pelo menos tão acessível quanto o operador, ou reduza a acessibilidade do operador para corresponder ao tipo de retorno (CS0056). Um operador public não pode expor um tipo menos acessível através do seu valor de retorno porque os chamadores fora da assembly não conseguiriam usar o resultado.
  • Mude o tipo de parâmetro para um tipo que seja pelo menos tão acessível quanto o operador, ou reduza a acessibilidade do operador para corresponder ao tipo de parâmetro (CS0057). Um public operador não pode exigir um tipo menos acessível como parâmetro porque os chamadores fora do conjunto não conseguiriam fornecer o argumento.

Restrições de conversão definidas pelo usuário

  • CS0552: Conversão definida pelo usuário para/da interface.
  • CS0553: Conversão definida pelo usuário de/para a classe base.
  • CS0554: Conversão definida pelo usuário para/da classe derivada.
  • CS0555: O operador definido pelo utilizador não pode aceitar um objeto do tipo envolvente e converter para um objeto do tipo envolvente.
  • CS0556: A conversão definida pelo usuário deve ser convertida de ou para o tipo de anexo.
  • CS0557: Duplicar a conversão definida pelo usuário no tipo.

A linguagem C# restringe que tipos podem participar em conversões definidas pelo utilizador. Para as regras completas, veja Operadores de conversão definidos pelo utilizador e Operadores de conversão na especificação C#.

  • Remover o operador de conversão que converte para ou a partir de um tipo de interface (CS0552). A linguagem de programação proíbe conversões definidas pelo utilizador envolvendo tipos de interface porque as conversões de interface são tratadas através das conversões de referência e empacotamento (boxing) do sistema de tipos. Use implementações explícitas de interface ou métodos auxiliares em vez disso.
  • Remover o operador de conversão que converte para ou a partir de uma classe base (CS0553). As conversões entre um tipo e a sua classe base já existem através de conversões de referência implícitas (upcast) e conversões explícitas de referência (downcast), pelo que uma conversão definida pelo utilizador criaria ambiguidade.
  • Remova o operador de conversão que converte para ou a partir de uma classe derivada (CS0554). Tal como as conversões de classes base, as conversões entre um tipo e os seus tipos derivados são incorporadas na linguagem através da herança, e as conversões definidas pelo utilizador entrariam em conflito com elas.
  • Remova o operador de conversão que converte o tipo envolvente para si próprio (CS0555). Cada tipo já tem uma conversão implícita de identidade para si próprio, por isso uma conversão definida pelo utilizador de um tipo para o mesmo tipo é redundante e não é permitida.
  • Altere um dos tipos no operador de conversão para que o tipo de origem ou de destino seja o tipo envolvente (CS0556). Uma conversão definida pelo utilizador deve envolver o tipo que a declara — não se pode definir uma conversão entre dois tipos externos não relacionados num terceiro tipo.
  • Remova o operador de conversão duplicada, ou altere um dos operadores duplicados para que os tipos de origem e destino difiram dos outros (CS0557). Um tipo pode declarar apenas uma conversão implícita e uma conversão explícita para qualquer par dado de tipos de origem e destino.

Operadores booleanos e de curto-circuito

  • CS0215: O tipo de retorno do operador true ou false deve ser bool.
  • CS0216: O operador requer que um operador correspondente também seja definido.
  • CS0217: Para ser aplicável como um operador de curto-circuito, um operador lógico definido pelo usuário deve ter o mesmo tipo de retorno que o tipo de seus 2 parâmetros.
  • CS0218: O tipo deve conter declarações de operador true e operador false.

A linguagem C# requer emparelhamentos e assinaturas específicas para operadores booleanos e avaliação de curtos-circuitos. Para as regras completas, veja operadores verdadeiros e falsos, operadores lógicos booleanos e operadores lógicos condicionais definidos pelo utilizador na especificação C#.

  • Mude o tipo de retorno de operator true e operator false para bool (CS0215). Estes operadores determinam se um valor é logicamente verdadeiro ou falso, pelo que a linguagem exige que devolvam bool.
  • Defina o operador emparelhado correspondente (CS0216). A linguagem exige que certos operadores sejam declarados em pares: operator == com operator !=, operator < com operator >, operator <= com operator >=, e operator true com operator false.
  • Altere o tipo de retorno do operador definido &| pelo utilizador para corresponder a ambos os tipos de parâmetros (CS0217). Para a avaliação de curto-circuito (&& e ||), o compilador exige que o tipo de retorno do operador &, ambos os tipos de parâmetro | e o tipo que contém sejam todos do mesmo tipo.
  • Adicione ambas as declarações operator true e operator false ao tipo (CS0218). O compilador reescreve && e || usando operator true, operator false e o operador correspondente & ou |, pelo que todos os três devem estar presentes para que a avaliação de curto-circuito possa ocorrer.

Operadores controlados

  • CS9023: O operador não pode ser verificado
  • CS9024: O operador não pode ser desmarcado
  • CS9025: O operador verificado requer que uma versão correspondente não verificada também seja declarada
  • CS9027: Palavra-chave inesperada 'unchecked'

As checked palavras-chave e unchecked só podem ser aplicadas a declarações específicas de operadores. Para as regras completas, veja Operadores aritméticos e Operadores verificados definidos pelo utilizador.

  • Remover a checked palavra-chave ou unchecked de um operador não suportado (CS9023, CS9024). Apenas os operadores +aritméticos , -, *, /, , ++, --, e operadores explícitos de conversão suportam variantes verificadas e não marcadas. Outros operadores, como os operadores de comparação ou igualdade, não apresentam comportamentos de overflow distintos e não podem ser marcados como verificados ou não verificados.
  • Adicione uma versão do operador que corresponda e não esteja assinalada (CS9025). Um checked operador fornece o comportamento de lançamento de overflow, mas o compilador também necessita da versão correspondente não verificada para ser usada em unchecked contextos e como padrão quando nenhum dos contextos é especificado.
  • Remover a unchecked palavra-chave da posição inválida (CS9027). A unchecked palavra-chave numa declaração de operador só é válida como parte da sintaxe do operador (por exemplo, public static explicit operator unchecked int(MyType t)). Colocá-la noutro local da declaração causa um erro de sintaxe.

Requisitos de interface e herança

  • CS9311: O tipo não implementa o membro da interface. O tipo não pode implementar membro porque um deles não é um operador
  • CS9312: Tipo não pode substituir membro herdado porque um deles não é um operador
  • CS9313: Operador de atribuição composto sobrecarregado recebe um parâmetro

O compilador impõe uma correspondência rigorosa entre declarações de operador e os membros da interface ou da classe base que implementam ou sobrescrevem. Para as regras completas, veja Sobrecarga do Operador e Interfaces.

  • Altere o membro implementador para uma declaração de operador que corresponda ao membro operador da interface, ou mude o membro da interface para um método se o membro implementador for um método (CS9311). Um operador só pode implementar um membro de interface que também seja declarado como operador — não se pode satisfazer um contrato de operador com um método regular, ou vice-versa.
  • Altere o membro soberbio para uma declaração de operador que corresponda ao membro operador da classe base, ou altere o membro da classe base para um método se o membro de classe derivado for um método (CS9312). Tal como na implementação de interface, uma substituição deve corresponder ao tipo de membro que está a ser substituído — um operador não pode substituir um membro que não é operador.
  • Alterar a declaração do operador de atribuição composta para aceitar exatamente um parâmetro (CS9313). Os operadores de atribuição composta são membros de instância onde o operando esquerdo é implicitamente this, pelo que apenas o operando direito é declarado como parâmetro.

Operadores de igualdade

  • CS0659: 'class' sobrepõe Object.Equals(object o) mas não sobrepõe Object.GetHashCode()
  • CS0660: O tipo define o operador == ou o operador != mas não substitui Object.Equals(objeto o)
  • CS0661: Type define operador == ou operador != mas não substitui Object.GetHashCode()

O compilador exige que as sobrecargas relacionadas com a igualdade e as definições de operadores se mantenham sincronizadas. Quando substitui Object.Equals ou define operator == / operator !=, também deve fornecer as sobrecargas relacionadas. Para as regras completas, veja Como definir igualdade de valores para um tipo e operadores de igualdade.

  • Adicione uma substituição de Object.GetHashCode quando substituir Object.Equals (CS0659). Coleções baseadas em hash, como Dictionary<TKey,TValue> e HashSet<T> dependem do contrato de que dois objetos iguais devem devolver o mesmo código hash. Sem um override correspondente GetHashCode, objetos que são considerados iguais podem ser dispersados em buckets diferentes, fazendo com que as consultas e a deduplicação falhem silenciosamente.
  • Adicione um override de Object.Equals quando define operator == ou operator != (CS0660). O código que chama Equals diretamente — incluindo muitas APIs de framework, métodos LINQ e operações de recolha — não usará o seu operador personalizado. Sem uma sobreposição consistente Equals , os mesmos dois objetos podem ser considerados iguais por == , mas não por Equals, levando a comportamentos imprevisíveis.
  • Adicione um override de Object.GetHashCode quando define operator == ou operator != (CS0661). Tal como CS0659, é necessário GetHashCode ser consistente com a semântica de igualdade. Se operator == considerar dois objetos iguais mas eles devolverem códigos hash diferentes, as coleções baseadas em hash não funcionarão corretamente.

Erros de transbordo e de subfluxo

  • CS0031: Valor constante 'valor' não pode ser convertido num 'tipo'
  • CS0220: A operação transborda durante a compilação em modo controlado
  • CS0221: Valor constante 'valor' não pode ser convertido num 'tipo' (use a sintaxe 'unchecked' para substituir o valor padrão)
  • CS0463: Avaliação da expressão da constante decimal falhou com erro: 'erro'
  • CS0543: 'enumeração': o valor do enumerador é demasiado grande para caber no seu tipo
  • CS0594: A constante de ponto flutuante está fora do intervalo do tipo 'tipo'
  • CS0652: A comparação com a constante integral é inútil; a constante está fora do intervalo do tipo 'tipo'
  • CS1021: Constante integral é demasiado grande
  • CS8778: Valor constante 'valor' pode causar overflow no 'tipo' em tempo de execução (use a sintaxe 'unchecked' para sobrescrever)
  • CS8973: A operação pode transbordar em tempo de execução (use a sintaxe 'unchecked' para sobrepor)

O compilador avalia expressões constantes em tempo de compilação e reporta erros ou avisos quando um valor excede o intervalo válido do seu tipo-alvo. Para as regras completas, consulte instruções verificadas e não verificadas e tipos integrais.

  • Altere o valor constante para um que se ajuste ao alcance do tipo alvo, ou altere o alvo para um tipo numérico maior (CS0031). O compilador não pode restringir implicitamente uma constante que não se encaixa — por exemplo, atribuir 256 a um byte (intervalo 0–255) produz este erro. Se o truncamento for intencional, use um cast explícito no contexto de unchecked.
  • Corrigir a aritmética na expressão constante para que o resultado se ajuste ao tipo alvo, ou envolver a expressão no contexto não controlado para permitir o transbordamento silencioso (CS0220). O compilador avalia toda a expressão constante em tempo de compilação num contexto verificado por defeito, pelo que resultados intermédios ou finais que excedam o intervalo do tipo causam este erro.
  • Muda o valor constante ou o tipo alvo para que a conversão seja válida, ou envolve a expressão num unchecked contexto se quiseres intencionalmente o resultado truncado (CS0221). Ao contrário do CS0220, este erro aplica-se a conversões constantes explícitas onde o valor de origem não corresponde ao tipo de destino.
  • Simplifique ou fragmente a decimal expressão constante para que se mantenha dentro do alcance e precisão do decimal tipo (CS0463). O decimal tipo tem um valor máximo de aproximadamente $7.9 \times 10^{28}$ e 28 a 29 dígitos significativos, e o compilador analisa a expressão inteira durante a compilação.
  • Altere o valor do membro do enum para um que se encaixe no tipo subjacente do enum, ou altere o tipo subjacente para um tipo integral maior (CS0543). Por defeito, os enums usam int como tipo subjacente. Se o valor de um membro exceder o intervalo do tipo subjacente, especifique um tipo maior como long.
  • Mude a constante de ponto flutuante para um valor dentro do intervalo do tipo alvo, ou use um tipo de maior precisão como double em vez de float (CS0594). O float tipo suporta valores até aproximadamente $3,4 \times 10^{{38}} $, e double suporta até aproximadamente $1,7 \times 10^{{308}} $.
  • Remover ou corrigir a comparação para que a constante fique dentro do intervalo do tipo da variável (CS0652). Comparar uma byte variável com 300, por exemplo, nunca pode ser verdadeiro, por isso o compilador avisa que a comparação é inútil. Este aviso indica frequentemente um erro lógico ou uma incompatibilidade entre o tipo de variável e o intervalo pretendido de valores.
  • Use um tipo numérico maior ou divida o valor por várias operações (CS1021). Este erro ocorre quando um literal inteiro excede o intervalo até mesmo do maior tipo integral (ulong, até $1,8 \times 10^{19}$). Para valores além desse intervalo, considere usar BigInteger.
  • Envolva a expressão num unchecked contexto para suprimir o aviso, ou altere o valor para se ajustar ao intervalo do tipo alvo (CS8778). Este aviso indica uma conversão constante que pode perder dados em tempo de execução — o compilador não pode provar que o overflow vai acontecer de certeza, mas identifica o risco.
  • Envolva a expressão num unchecked contexto para suprimir o aviso, ou reestruture a aritmética para evitar um potencial desbordamento (CS8973). Este aviso é semelhante ao CS8778 , mas aplica-se a operações aritméticas em vez de conversões — o compilador deteta que a operação pode transbordar em tempo de execução.