Compartilhar via


Erros e avisos ao usar expressões lambda e funções anônimas

Vários erros estão relacionados à declaração e ao uso de expressões lambda e métodos anônimos:

  • CS0407: 'method' tem o tipo de retorno errado.
  • CS0428: não é possível converter o grupo de métodos 'Identifier' em tipo não delegado 'type'. Você pretendia invocar o método?
  • CS0748: uso inconsistente de parâmetro lambda; os tipos de parâmetro devem ser todos explícitos ou todos implícitos.
  • CS0815: Não é possível atribuir "expressão" a uma variável de tipo implícito.
  • CS0828: não é possível atribuir 'expressão' à propriedade de tipo anônimo.
  • CS0837: O primeiro operando de um operador 'is' ou 'as' pode não ser uma expressão lambda, um método anônimo ou um grupo de métodos.
  • CS1065: os valores padrão não são válidos neste contexto.
  • CS1621: A instrução de rendimento não pode ser usada dentro de um método anônimo ou expressão lambda.
  • CS1628: não é possível usar inref ou out parâmetro dentro de um método anônimo, expressão lambda ou expressão de consulta.
  • CS1632: O controle não pode deixar o corpo de um método anônimo ou expressão lambda.
  • CS1643: nem todos os caminhos de código retornam um valor no método anônimo do tipo 'type'.
  • CS1660: Não é possível converter a expressão lambda para o tipo 'type' porque ela não é um tipo delegado.
  • CS1661: Não é possível converter o bloco de método anônimo para o tipo 'type' porque os tipos de parâmetro não correspondem aos tipos de parâmetro delegado.
  • CS1662: Não é possível converter o bloco de método anônimo para o tipo de delegado pretendido porque alguns dos tipos de retorno no bloco não são implicitamente conversíveis para o tipo de retorno delegado.
  • CS1673: métodos anônimos, expressões lambda e expressões de consulta dentro de structs não podem acessar membros da instância 'this'.
  • CS1676: o parâmetro 'number' deve ser declarado com a palavra-chave 'keyword'.
  • CS1677: o parâmetro 'number' não deve ser declarado com a palavra-chave 'keyword'.
  • CS1678: o parâmetro 'number' é declarado como o tipo 'type1', mas deve ser 'type2'.
  • CS1686: A variável local ou seus membros não podem ter seu endereço tomado e ser usado dentro de um método anônimo ou expressão lambda.
  • CS1688: Não é possível converter o bloco de método anônimo sem uma lista de parâmetros para delegar o tipo 'delegate' porque ele tem um ou mais parâmetros externos.
  • CS1706: A expressão não pode conter métodos anônimos ou expressões lambda.
  • CS1731: Não é possível converter a expressão em delegado porque alguns dos tipos de retorno no bloco não são implicitamente conversíveis para o tipo de retorno delegado.
  • CS1732: parâmetro esperado.
  • CS1764: Não é possível usar local fixo dentro de um método anônimo, expressão lambda ou expressão de consulta.
  • CS8030: A função anônima convertida em um delegado de retorno nulo não pode retornar um valor.
  • CS8175: Não é possível usar ref local dentro de um método anônimo, expressão lambda ou expressão de consulta.
  • CS8820: uma função anônima estática não pode conter uma referência à "variável".
  • CS8821: uma função anônima estática não pode conter uma referência a 'this' ou 'base'.
  • CS8916: atributos em expressões lambda exigem uma lista de parâmetros parênteses.
  • CS8917: O tipo delegado não pôde ser inferido.
  • CS8934: Não é possível converter o método anônimo para o tipo 'type' porque o tipo de retorno não corresponde ao tipo de retorno do delegado.
  • CS8975: A palavra-chave var contextual não pode ser usada como um tipo de retorno lambda explícito.
  • CS9098: parâmetro lambda tipado implicitamente '...' não pode ter um valor padrão.

Além disso, vários avisos estão relacionados à declaração e ao uso de expressões lambda:

  • CS0467: ambiguidade entre o método 'method' e o não método 'non-method'. Usando o grupo de métodos.
  • CS1911: o acesso ao membro por meio de uma palavra-chave 'base' de um método anônimo, expressão lambda, expressão de consulta ou iterador resulta em código inverificável.
  • CS8971: InterpolatedStringHandlerArgument não tem efeito quando aplicado aos parâmetros lambda e será ignorado no site de chamada.
  • CS8974: convertendo o grupo de métodos 'method' em 'type' do tipo não delegado. Você pretendia invocar o método?
  • CS9099: O valor do parâmetro padrão não corresponde ao tipo de delegado de destino.
  • CS9100: o parâmetro tem modificador de params no lambda, mas não no tipo delegado de destino.

O compilador também produz a seguinte mensagem informativa :

  • CS9236: A compilação requer a associação da expressão lambda pelo menos o número de vezes especificado. Considere declarar a expressão lambda com tipos de parâmetro explícitos ou, se o método de chamada for genérico, considere usar argumentos de tipo explícitos.

Limitações de sintaxe em expressões lambda

  • CS0837: O primeiro operando de um operador is ou as não pode ser uma expressão lambda, um método anônimo ou um grupo de métodos.
  • CS1621: A yield instrução não pode ser usada dentro de um método anônimo ou expressão lambda.
  • CS1628: Não é possível usar in, refou out parâmetro dentro de um método anônimo, expressão lambda ou expressão de consulta.
  • CS1632: O controle não pode deixar o corpo de um método anônimo ou expressão lambda.
  • CS1673: métodos anônimos, expressões lambda e expressões de consulta dentro de structs não podem acessar membros da instância de this.
  • CS1686: A variável local ou seus membros não podem ter seu endereço tomado e ser usado dentro de um método anônimo ou expressão lambda.
  • CS1706: A expressão não pode conter métodos anônimos ou expressões lambda.
  • CS1764: Não é possível usar local fixo dentro de um método anônimo, expressão lambda ou expressão de consulta.
  • CS1911: Aviso: o acesso ao membro por meio de uma palavra-chave 'base' de um método anônimo, expressão lambda, expressão de consulta ou iterador resulta em código inverificável.
  • CS8175: Não é possível usar ref local dentro de um método anônimo, expressão lambda ou expressão de consulta.
  • CS8820: uma função anônima estática não pode conter uma referência à "variável".
  • CS8821: uma função anônima estática não pode conter uma referência a 'this' ou 'base'.
  • CS8971: Aviso: InterpolatedStringHandlerArgument não tem efeito quando aplicado aos parâmetros lambda e será ignorado no site de chamada.
  • CS9236: Informativo: A compilação requer a vinculação da expressão lambda pelo menos um número específico de vezes. Considere declarar a expressão lambda com tipos de parâmetros explícitos ou, se a chamada do método que a contém for genérica, considere usar argumentos de tipo explícitos.

O compilador proíbe determinadas construções em C# dentro de expressões lambda e métodos anônimos. Essas restrições existem porque o compilador transforma lambdas e métodos anônimos em invocações delegadas ou árvores de expressão, e algumas construções não podem ser representadas nessas formas. Para obter mais informações, consulte a seção de expressões de função anônima da especificação C#.

Você pode corrigir esses erros usando as seguintes diretrizes:

  • Mova qualquer yield return instrução para yield break fora do corpo lambda e no método iterador que o delimita, ou converta o lambda em uma função local, que oferece suporte a instruções yield (CS1621).
  • Evite referenciar in, refou out parâmetros do método delimitante dentro do corpo lambda. Quando o lambda captura esses parâmetros como parte de um fechamento, a semântica de referência de refparâmetros semelhantes não pode ser preservada. Copie o valor para uma variável local e use essa variável, ou converta o lambda em uma função local (CS1628).
  • Remova qualquer instrução break, goto ou continue que transfira o controle para fora do corpo da expressão lambda. As declarações de fluxo de controle devem direcionar rótulos ou loops dentro do mesmo corpo lambda (CS1632).
  • Em um struct tipo, evite referenciar membros de instância dentro de uma expressão lambda, método anônimo ou expressão de consulta por meio de this. Como o compilador captura this por valor em um struct, mutações dentro do lambda não afetam a instância original. Extraia os valores de membro necessários em variáveis locais antes do lambda ou converta em uma função local, que pode acessar this diretamente (CS1673).
  • Não pegue o endereço de uma variável local que o lambda também captura. O compilador move variáveis capturadas para um objeto de fechamento alocado na heap, o que torna seu endereço instável. Separe a lógica de tomada de endereço do lambda ou use uma função local em vez disso (CS1686).
  • Mova a expressão lambda ou o método anônimo para fora da expressão que a proíbe. Algumas expressões, como construtores de atributos, não dão suporte a expressões lambda ou métodos anônimos como argumentos (CS1706).
  • Não use uma fixed variável local dentro de um corpo lambda. A garantia de fixação da fixed instrução se aplica somente ao escopo delimitador, não ao fechamento gerado pelo compilador (CS1764).
  • Não use um ref local dentro de um corpo lambda. Assim como os ref parâmetros, os ref locais não podem ser capturados no fecho que o compilador gera para o lambda. Atribua o valor a uma variável nãoref local ou converta o lambda em uma função local (CS8175).
  • Não use uma expressão lambda, um método anônimo ou um grupo de métodos como o primeiro operando do operador is ou as. Esses constructos não têm um tipo que pode ser testado em tempo de execução. Atribua a expressão a uma variável primeiro e teste a variável (CS0837).
  • Remova o static modificador do lambda ou remova a referência à variável capturada. Um static lambda proíbe explicitamente a captura de variáveis locais ou parâmetros para evitar alocações de closure não intencionadas. Se você precisar fazer referência a variáveis externas, remova o static modificador. Se você quiser manter a alocação de heap mínima, passe os valores como parâmetros para o lambda (CS8820, CS8821).
  • Remova o parâmetro lambda InterpolatedStringHandlerArgumentAttribute ou mova a lógica para um método em que o atributo seja respeitado. O compilador ignora esse atributo nos parâmetros lambda porque as invocações lambda não usam o mesmo rebaixamento do manipulador de cadeia de caracteres interpolada como as chamadas de método regulares (CS8971).
  • Evite chamar um membro virtual por meio da base palavra-chave dentro de um método lambda ou anônimo. O compilador gera uma chamada não virtual por meio de um método auxiliar, que produz código não verificável. Considere extrair a base chamada em um método separado e chamar esse método a partir do lambda (CS1911).
  • Reduza a complexidade das chamadas de método sobrecarregadas que aceitam expressões lambda ou adicionam informações de tipo explícitas. Quando o compilador deve associar uma expressão lambda várias vezes para resolver sobrecargas, ele emite esse diagnóstico informativo. Declarar o lambda com tipos de parâmetro explícitos ou fornecer argumentos de tipo explícitos na chamada de método genérico reduz o número de passes de associação que o compilador deve executar (CS9236).

Parâmetros de expressão Lambda e retornos

  • CS0748: uso inconsistente de parâmetro lambda; os tipos de parâmetro devem ser todos explícitos ou todos implícitos.
  • CS1065: os valores padrão não são válidos neste contexto.
  • CS1643: nem todos os caminhos de código retornam um valor no método anônimo do tipo 'type'.
  • CS1661: Não é possível converter o bloco de método anônimo para o tipo 'type' porque os tipos de parâmetro não correspondem aos tipos de parâmetro delegado.
  • CS1662: Não é possível converter o bloco de método anônimo para o tipo de delegado pretendido porque alguns dos tipos de retorno no bloco não são implicitamente conversíveis para o tipo de retorno delegado.
  • CS1676: o parâmetro 'number' deve ser declarado com a palavra-chave 'keyword'.
  • CS1677: o parâmetro 'number' não deve ser declarado com a palavra-chave 'keyword'.
  • CS1678: o parâmetro 'number' é declarado como o tipo 'type1', mas deve ser 'type2'.
  • CS1688: Não é possível converter o bloco de método anônimo sem uma lista de parâmetros para delegar o tipo 'delegate' porque ele tem um ou mais parâmetros externos.
  • CS1731: Não é possível converter a expressão em delegado porque alguns dos tipos de retorno no bloco não são implicitamente conversíveis para o tipo de retorno delegado.
  • CS1732: parâmetro esperado.
  • CS8030: A função anônima convertida em um delegado de retorno nulo não pode retornar um valor.
  • CS8916: atributos em expressões lambda exigem uma lista de parâmetros parênteses.
  • CS8934: Não é possível converter o método lambda para o tipo 'type' porque seu tipo de retorno não corresponde ao tipo de retorno do delegado.
  • CS8975: A palavra-chave contextual 'var' não pode ser usada como um tipo de retorno lambda explícito.
  • CS9098: parâmetro lambda tipado implicitamente '...' não pode ter um valor padrão.

Esses erros indicam um problema com um parâmetro de expressão lambda ou declaração de tipo de retorno. Para obter as regras completas sobre parâmetro lambda e tipos de retorno, consulte expressões lambda, métodos anônimos e a seção de expressões de função anônima da especificação C#.

Observação

CS1731 e CS1732 não são mais produzidos pela versão atual do compilador C# (Roslyn). Eles podem aparecer se você estiver usando uma versão mais antiga do compilador.

Você pode corrigir esses erros usando as seguintes diretrizes:

  • Verifique se todos os parâmetros em uma expressão lambda usam o mesmo estilo de digitação. Quando um lambda tem vários parâmetros, cada parâmetro deve ser digitado explicitamente ou digitado implicitamente, não é possível misturar os dois estilos na mesma lista de parâmetros (CS0748).
  • Adicione tipos explícitos a qualquer parâmetro lambda que tenha um valor padrão. O compilador requer tipos explícitos em parâmetros com padrões porque deve gerar um tipo de delegado personalizado que codifica o valor padrão. Parâmetros tipados implicitamente não fornecem informações suficientes ao compilador para construir aquele tipo de delegado (CS1065, CS9098).
  • Remova valores de parâmetro padrão de métodos anônimos declarados usando o delegate operador. Os valores de parâmetro padrão têm suporte apenas em expressões lambda, não em métodos anônimos. Converta o método anônimo em uma expressão lambda se precisar de valores padrão (CS1065).
  • Correlacione os tipos de parâmetro, ref/out/in modificadores e a quantidade de parâmetros do método lambda ou anônimo com o tipo delegado de destino. O compilador executa uma correspondência exata de assinaturas de parâmetro ao converter uma função anônima em um delegado: cada parâmetro deve ter o tipo correto e qualquer ref, outou in modificador deve estar presente exatamente quando o delegado espera (CS1661, CS1676, CS1677, CS1678).
  • Adicione uma lista de parâmetros ao método anônimo quando o tipo de delegado de destino tiver out parâmetros. Um método anônimo declarado sem uma lista de parâmetros (usando delegate { } sintaxe) pode corresponder à maioria dos tipos delegados, mas o compilador não pode sintetizar os parâmetros necessários out implicitamente. Declare os parâmetros explicitamente para corresponder à assinatura delegada (CS1688).
  • Verifique se todos os caminhos de código no método lambda ou anônimo retornam um valor quando o tipo de delegado de destino tiver um tipo de retorno não nulo. Cada ramificação dentro do corpo deve produzir um valor de retorno que seja implicitamente conversível para o tipo de retorno do delegado (CS1643, CS1662, CS1731, CS8934).
  • Remova qualquer return instrução com um valor de um método lambda ou anônimo atribuído a um voidtipo delegado de retorno, como Action. Como o tipo de retorno do delegado é void, o corpo não pode retornar um valor (CS8030).
  • Coloque a lista de parâmetros entre parênteses quando os atributos forem aplicados a qualquer parâmetro lambda. O compilador precisa da forma entre parênteses para distinguir a sintaxe de atributos de outras expressões. Por exemplo, escreva ([MyAttribute] int x) => x em vez de [MyAttribute] x => x (CS8916).
  • Use um nome de tipo específico em vez de var como o tipo de retorno explícito de uma expressão lambda. A palavra-chave var é reservada para variáveis locais tipadas implicitamente e não pode ser usada como uma anotação de tipo de retorno lambda. Especifique o tipo de retorno real ou omita o tipo de retorno e deixe o compilador inferi-lo (CS8975).
  • Corrija a lista de parâmetros para que o compilador possa reconhecê-la como uma declaração de parâmetro válida. Esse erro indica uma lista de parâmetros malformados em que o compilador esperava um identificador de parâmetro, mas encontrou outra coisa (CS1732).

Tipo de delegado para expressão Lambda

  • CS0407: 'method' tem o tipo de retorno errado.
  • CS0428: não é possível converter o grupo de métodos 'Identifier' em tipo não delegado 'type'. Você pretendia invocar o método?
  • CS0467: Aviso: Ambiguidade entre o método 'method' e o não-método 'non-method'. Utilizando o grupo de métodos.
  • CS0815: Não é possível atribuir "expressão" a uma variável de tipo implícito.
  • CS0828: não é possível atribuir 'expressão' à propriedade de tipo anônimo.
  • CS1660: Não é possível converter a expressão lambda para o tipo 'type' porque ela não é um tipo delegado.
  • CS8917: O tipo delegado não pôde ser inferido.
  • CS8974: Aviso: Convertendo o grupo de métodos 'method' para um tipo não delegado 'type'. Você pretendia invocar o método?
  • CS9099: Aviso: o valor do parâmetro padrão não corresponde ao tipo de delegado de destino.
  • CS9100: Aviso: o parâmetro tem modificador de params no lambda, mas não no tipo delegado de destino.

Esses erros indicam um problema com o tipo delegado que o compilador infere ou espera para uma expressão lambda, um método anônimo ou um grupo de métodos. Para obter as regras completas sobre conversões de delegado, consulte expressões lambda, métodos anônimos e a seção de funções anônimas da especificação C#.

Observação

A versão atual do compilador C# (Roslyn) não produz CS0467. Você poderá ver esse erro se estiver usando uma versão mais antiga do compilador.

Você pode corrigir esses erros usando as seguintes diretrizes:

  • Verifique se o tipo de destino da atribuição ou conversão é um tipo delegado ou System.Linq.Expressions.Expression. Uma expressão lambda ou um método anônimo não pode ser atribuído a um tipo não delegado, como object ou a uma interface. Altere o tipo da variável para um tipo de delegado compatível, como Func<> ou Action<>, ou use var para permitir que o compilador infera o tipo delegado (CS1660).
  • Forneça contexto suficiente para o compilador determinar um único tipo de delegado para a expressão lambda. Quando atribuído a var, o compilador precisa de um tipo de retorno inequívoco e uma lista de parâmetros. Quando atribuído a uma propriedade de tipo anônimo, o compilador não pode inferir um tipo de delegado. Atribua o lambda a uma variável com um tipo de delegado explícito e use essa variável no inicializador de tipo anônimo (CS0815, CS0828, CS8917).
  • Corresponda o tipo de retorno do grupo de métodos ao tipo de retorno declarado do delegado. Uma conversão de grupo de métodos requer que o tipo de retorno do método seja conversível por identidade ou implicitamente conversível para o tipo de retorno do delegado. Altere o tipo de retorno do método ou altere o tipo de delegado para corresponder (CS0407).
  • Invoque o método em vez de atribuir o grupo de métodos quando o tipo de destino não for um delegado. Se o tipo de destino for string, intou outro tipo não delegado, você provavelmente pretende chamar o método e atribuir seu resultado. Adicione parênteses e argumentos para invocar o método (CS0428, CS8974).
  • Resolva a ambiguidade entre um método e um membro não método que compartilhe o mesmo nome. Renomeie um dos membros conflitantes ou use uma referência totalmente qualificada para remover a ambiguidade (CS0467).
  • Remova o valor de parâmetro padrão ou params do lambda quando o tipo de delegado de destino for um tipo padrão Func<> ou Action<>. Os valores padrão e params modificadores levam o compilador a gerar um tipo de delegado personalizado que não corresponde a Func<> ou Action<>. Use var para permitir que o compilador sintetize o tipo de delegado correto ou remova o valor ou params modificador padrão para que o lambda corresponda ao tipo delegado declarado (CS9099, CS9100).