2010-02-22 17 views
13

Esta es solo una pregunta "Soy curioso".C# - ¿Cómo crear un ciclo infinito no detectable?

En C# -en profundidad Jon Skeet dice acerca de las expresiones lambda:
"Si hay un tipo de retorno nonvoid cada ruta de código tiene que devolver un valor compatible" (Página 233)

La nota al pie luego dice: "
rutas de código que lanzan excepciones no tienen que devolver un valor, por supuesto, y tampoco lo hacen los bucles infinitos detectables." (Página 233)

Me pregunto qué constituye un ciclo infinito no detectable?

¿Se puede hacer esto solo por lógica? ¿o se hace usando factores externos como una base de datos o un sistema de archivos?

+0

@JonSkeet tal vez él puede aclarar. –

Respuesta

21

lo que Jon se refiere es descrito en la sección 8.1 de la especificación. El compilador puede detectar sólo muy simples bucles infinitos, como:

while(true) { if (0 != 0) return 123; } 

el compilador es suficientemente inteligente como para ver que no se alcanza nunca el retorno, y por lo tanto que el bucle se ejecuta siempre. Es legal, aunque loco, para decir:

int M() { while(true) { } } 

porque aunque no hay un camino que devuelve un int, también hay ningún camino que devuelve sin devolver un int!

El compilador no es lo suficientemente inteligente como para encontrar otros tipos de bucles infinitos. Por ejemplo:

int x = 123; 
while(true) { if (x * 0 != 0) break; } 

Esto es claramente un ciclo infinito. Pero el compilador no lo sabe. El compilador dice "bueno, tal vez haya algún valor de x donde x * 0 no sea cero, entonces el salto es alcanzable, por lo que este no es un ciclo infinito". Tú y yo sabemos que esto es imposible porque sabemos matemáticas, pero el compilador no.

Lea la sección 8.1 si desea los detalles.

+3

Realmente no recuerdo haber escrito esto, lo que sugiere que la nota al pie se debe a tu influencia :) –

+2

@Jon: Originalmente escribiste "Las rutas de código arrojando excepciones no necesitan devolver un valor, por supuesto". Noté que los bucles infinitos detectables también cuentan como puntos finales inalcanzables. –

+2

Derecha: parece un nivel de detalle más probable para cada uno de nosotros :) –

3

Es bastante trivial crear un bucle infinito usando fuentes externas, o incluso abusando de herramientas como interfaces.

Por ejemplo:

public interface INumbers 
    { 
     int GetNumber(int arg); 
    } 
    public class StaticNumber : INumbers 
    { 
     public int GetNumber(int arg) 
     { 
      return 1; 
     } 
    } 
    public void DoStuff(INumbers num) 
    { 
     int i = 42; 
     while ((i = num.GetNumber(i)) != 0) 
     { 
      ; 
     } 
    } 

y luego un simple

Action action =() => DoStuff(new StaticNumber()); 
Cuestiones relacionadas