Errores y advertencias al usar expresiones lambda y funciones anónimas
Hay varios errores relacionados con la declaración y el uso de expresiones lambda:
- CS0748: uso incoherente del parámetro lambda. Los tipos de parámetro deben ser todos explícitos o todos implícitos.
- CS1621: la instrucción yield no se puede usar dentro de un método anónimo o una expresión lambda.
- CS1628: no se pueden usar los parámetros
in
ref
oout
dentro de un método anónimo, una expresión lambda o una expresión de consulta. - CS1632: El control no puede abandonar el cuerpo de un método anónimo o de una expresión lambda.
- CS1673: los métodos anónimos, las expresiones lambda y las expresiones de consulta incluidos en estructuras no pueden tener acceso a miembros de instancia de "this".
- CS1686: No puede tomarse la dirección de la variable local o sus miembros y usarse en un método anónimo o una expresión lambda.
- CS1706: la expresión no puede contener métodos anónimos ni expresiones lambda.
- CS8030: una función anónima convertida en un delegado que devuelve void no puede devolver un valor.
- CS8175: No se puede usar la variable local de tipo ref dentro de un método anónimo, una expresión lambda o una expresión de consulta.
- CS8916: los atributos de expresiones lambda requieren una lista de parámetros entre paréntesis.
- CS8971: el argumento InterpolatedStringHandlerArgument no tiene ningún efecto cuando se aplica a parámetros lambda y se omitirá en el sitio de llamada.
- CS8975: la palabra clave contextual
var
no se puede usar como un tipo de valor devuelto lambda explícito. - CS9098: el parámetro lambda con tipo implícito "..." no puede tener un valor predeterminado.
Además, hay varias advertencias relacionadas con la declaración y el uso de expresiones lambda:
- CS8971: el argumento InterpolatedStringHandlerArgument no tiene ningún efecto cuando se aplica a parámetros lambda y se omitirá en el sitio de llamada.
- CS9099: el valor del parámetro predeterminado no coincide en el tipo delegado de destino.
- CS9100: el parámetro tiene modificador de parámetros en lambda, pero no en el tipo delegado de destino.
Limitaciones de sintaxis en expresiones lambda
Alguna sintaxis de C# está prohibida en expresiones lambda y métodos anónimos. El uso de construcciones no válidas en una expresión lambda genera los siguientes errores:
- CS1621: La instrucción
yield
no se puede usar dentro de un método anónimo o una expresión lambda. - CS1628: No se pueden usar los parámetros
in
,ref
oout
dentro de un método anónimo, una expresión lambda o una expresión de consulta. - CS1632: El control no puede abandonar el cuerpo de un método anónimo o de una expresión lambda.
- CS1673: Los métodos anónimos, las expresiones lambda y las expresiones de consulta incluidos en estructuras no pueden tener acceso a miembros de instancia de
this
. - CS1686: No puede tomarse la dirección de la variable local o sus miembros y usarse en un método anónimo o una expresión lambda.
- CS8175: No se puede usar la variable local de tipo ref dentro de un método anónimo, una expresión lambda o una expresión de consulta.
No se permiten todas las construcciones siguientes en expresiones lambda:
- Instrucciones
yield
(yield return
oyield break
) - Llamada a un método que tiene un parámetro
in
,ref
oout
- Variables locales
ref
- Instrucciones
break
,goto
ycontinue
- Acceso a
this
cuandothis
es un tipostruct
- Métodos anónimos o expresiones lambda dentro de otra expresión, como un constructor de atributos.
No se puede usar ninguna de estas construcciones en una expresión lambda ni en un método anónimo. Se admiten muchas en una función local.
Además, los tipos de controlador de cadenas interpoladas se ignoran cuando se aplican a un parámetro lambda. Si usa alguno, verá la advertencia siguiente:
- CS8971: el argumento InterpolatedStringHandlerArgument no tiene ningún efecto cuando se aplica a parámetros lambda y se omitirá en el sitio de llamada.
Devoluciones y parámetros de expresiones lambda
Estos errores indican un problema con una declaración de parámetro:
- CS0748: uso incoherente del parámetro lambda. Los tipos de parámetro deben ser todos explícitos o todos implícitos.
- CS9098: el parámetro lambda con tipo implícito "..." no puede tener un valor predeterminado.
- CS8030: una función anónima convertida en un delegado que devuelve void no puede devolver un valor.
- CS8916: los atributos de expresiones lambdavrequieren una lista de parámetros entre paréntesis.
- CS8975: la palabra clave contextual "var" no se puede usar como un tipo de valor devuelto lambda explícito.
Los parámetros de expresión lambda deben seguir estas reglas:
- Cuando una expresión lambda tiene varios parámetros, todos ellos deben escribirse explícitamente o todos deben escribirse implícitamente.
- Todos los parámetros lambda con un valor predeterminado deben escribirse explícitamente.
- Si los atributos se aplican a cualquier parámetro, la lista de parámetros debe ir entre paréntesis.
Los tipos devueltos de expresión lambda deben seguir estas reglas:
- Una expresión lambda que devuelve cualquier valor no se puede convertir en un delegado devuelto
void
, comoAction
. - El tipo de valor devuelto se infiere, o un tipo explícito. No se permite un tipo de valor devuelto declarado mediante la palabra clave
var
.
Tipo de delegado de expresión lambda
- CS9099: advertencia: el valor del parámetro predeterminado no coincide en el tipo delegado de destino.
Cuando se declara un valor predeterminado o se agrega el modificador params
con un parámetro de expresión lambda, el tipo delegado no es ninguno de los tipos Func
o Action
. En su lugar, es un tipo personalizado que incluye el valor de parámetro predeterminado o el modificador params
. El código siguiente genera advertencias porque asigna una expresión lambda que tiene un parámetro predeterminado a un tipo Action
:
Action<int> a1 = (int i = 2) => { };
Action<string[]> a3 = (params string[] s) => { };
Para corregir el error, quite el parámetro predeterminado o use una variable con tipo implícito para el tipo delegado:
Action<int> a1 = (int i) => { };
var a2 = (int i = 2) => { };
Action<string[]> a3 = (string[] s) => { };
var a4 = (params string[] s) => { };