Errores y advertencias relacionados con los métodos de instrucción y de iterador yield return
Hay numerosos errores relacionados con los métodos de instrucción y de iterador yield return
:
- CS1622: No se puede devolver un valor de un iterador. Use la instrucción yield return para devolver un valor o yield break para finalizar la iteración.
- CS1624: El cuerpo del descriptor "accessor" no puede ser un bloque de iteradores porque 'type' no es un tipo de interfaz de iteradores
- CS1625: No se pueden producir resultados en el cuerpo de una cláusula finally
- CS1626: No se puede producir un valor en el cuerpo de un bloque try con una cláusula catch
- CS1627: Se esperaba una expresión tras la instrucción yield return
- CS1629: No puede aparecer código no seguro en iteradores
- CS1631: No se puede producir ningún valor en el cuerpo de una cláusula catch
- CS1637: Los iteradores no pueden tener parámetros unsafe o tipos yield
- CS4013: La instancia de tipo no se puede usar dentro de una función anidada, una expresión de consulta, un bloque de iteradores ni un método asíncrono
- CS8154: El cuerpo no puede ser un bloque de iteradores porque lo devuelve por referencia
- CS8176: Los iteradores no pueden tener variables locales por referencia
- CS9238: No se puede usar "yield return" en un bloque "unsafe"
- CS9239: El operador
&
no se puede utilizar en parámetros o variables locales en métodos de iterador
Estructura de un método de iterador
Un método de iterador debe cumplir varias reglas en C#. El compilador genera los errores siguientes cuando el método de iterador infringe una o varias de dichas reglas:
- CS1622: No se puede devolver un valor de un iterador. Use la instrucción yield return para devolver un valor o yield break para finalizar la iteración
- CS1624: El cuerpo del descriptor "accessor" no puede ser un bloque de iteradores porque 'type' no es un tipo de interfaz de iteradores
- CS1627: Se esperaba una expresión tras la instrucción yield return
- CS1637: Los iteradores no pueden tener parámetros unsafe o tipos yield
- CS8154: El cuerpo no puede ser un bloque de iteradores porque lo devuelve por referencia
El método de iterador debe seguir las reglas siguientes:
- Un método de iterador (mediante
yield return
y opcionalmente conyield break
) no puede usar tampoco una instrucciónreturn
para devolver una secuencia. - Un método de iterador debe declarar un tipo de interfaz de iteradores como tipo de valor devuelto. Los tipos de interfaz de iteradores son: IEnumerable, IEnumerable<T>, IEnumerator, IEnumerator<T>.
- Una instrucción
yield return
debe incluir una expresión para devolver como parte de una secuencia.yield return;
no es válido. - Un método de iterador no puede usar tipos unsafe a modo de parámetros, como punteros.
- Un método de iterador no puede hacer
yield return
un tipo unsafe, como punteros. - Un método de iterador no puede hacer
yield return
medianteref
. Se debe devolver mediante un valor.
Restricciones en los métodos de iterador
El cuerpo de un método de iterador debe cumplir las restricciones de la instrucción yield return
y su contexto. El compilador genera los siguientes errores cuando el iterador infringe una de estas restricciones:
- CS1625: No se pueden producir resultados en el cuerpo de una cláusula finally
- CS1626: No se puede producir un valor en el cuerpo de un bloque try con una cláusula catch
- CS1631: No se puede producir ningún valor en el cuerpo de una cláusula catch
- CS1629: No puede aparecer código no seguro en iteradores
- CS9238: No se puede usar "yield return" en un bloque "unsafe"
- CS9239: El operador
&
no se puede utilizar en parámetros o variables locales en métodos de iterador
Estos errores indican que el código infringe las reglas de seguridad porque un iterador devuelve un elemento y se reanuda para generar el elemento siguiente:
- No se puede hacer
yield return
en una cláusulacatch
ofinally
. - No se puede hacer
yield return
en un bloquetry
con una cláusula catch. - No se puede hacer
yield return
en un bloqueunsafe
. El contexto de un iterador crea un bloque anidadosafe
dentro del bloque contenedorunsafe
. - No se puede usar el operador
&
para tomar la dirección de una variable en un método de iterador.
Antes de C# 13, los iteradores no podían contener código unsafe
(CS1629). A partir de C# 13, esta restricción se ha flexibilizado. Todas las instrucciones yield return
deben estar en un contexto seguro, pero un método de iterador puede contener código unsafe
.
Seguridad de ref en métodos de iterador
Los métodos de iterador tienen restricciones especiales de seguridad de ref. Estas reglas se flexibilizan en C# 13:
- CS4013: La instancia de tipo no se puede usar dentro de una función anidada, una expresión de consulta, un bloque de iteradores ni un método asíncrono
- CS8176: Los iteradores no pueden tener variables locales por referencia
Antes de C# 13, los iteradores no podían declarar variables locales ref
. No podían declarar ninguna variable de un tipo ref struct
.
A partir de C# 13, los tipos de ref struct
se pueden usar en métodos de iterador, si no se tiene acceso a ellos en yield return
instrucción. A partir de C# 13, los métodos de iterador pueden declarar variables locales ref
.