2009-12-23 13 views
8

En C#, el siguiente método no se compilará:¿Por qué el compilador se comporta de manera diferente con este código?

public bool IsItTrue() 
{ 
} 

Los errores de compilación: 'IsItTrue()': no ​​todas las rutas de código devuelven un valor, el cual tiene mucho sentido. Pero la siguiente recopilación sin ningún problema.

public bool IsItTrue() 
{ 
    while (true) 
    { 
    } 
} 

Lo que parece incorrecto es que no haya ninguna declaración de devolución. ¿Por que es esto entonces? Cualquier ayuda aquí ...,

Respuesta

13

El compilador sabe que el segundo método nunca volverá.

Si cualquiera de los métodos vuelve alguna vez, deben devolver un bool.

El primer método no contiene ningún bucle infinito, no arroja ninguna excepción incondicional, etc., por lo que debe devolver un bool. El código no devuelve un bool por lo que el compilador se niega a compilarlo.

El segundo método nunca regresa debido al bucle infinito while (true). Si nunca devuelve, entonces no importa qué (si es que algo) es nunca se devolvió, por lo que el compilador lo permitirá compilar.

Un par de ejemplos más que el compilador reconocer y permitir:

public bool IsItTrue() 
{ 
    throw new Exception("Always thrown!"); 
} 

public bool HowAboutThisOne() 
{ 
    if ((46 - 3) < (27 * 9)) 
    { 
     throw new Exception("Always thrown!"); 
    } 
} 
+0

Poca explicación por favor .., – Dhana

+0

Es interesante que el compilador lo permita.Puedo ver por qué * podría * estar permitido, pero me pregunto qué propósito de la vida real sirve. –

+0

Sé que es posible que deseemos algo similar a un tiempo (verdadero) para un hilo, pero incluso un hilo debe terminar en algún momento? Entonces, si el compilador puede detectar tal situación, ¿por qué no arroja un punto de error en un ciclo infinito? – uriDium

3

La primera se explica muy bien por el mensaje de error del compilador.

El segundo nunca se regresa, así que hay Nunca cualquier valor devuelto.

No es lo mismo. En su primer ejemplo, el método podría regresar sin dar ningún valor a la persona que llama -> Error del compilador.

El segundo nunca volverá (el compilador es lo suficientemente inteligente para eso, se da cuenta de que ha creado un bucle infinito). Nunca ingresará el estado "Bien, llegué al final del método y no sé qué devolver".

1

El Halting Problem indica que generalmente no se puede determinar si un programa finalizará o se ejecutará para siempre. Dado que hay ejemplos en este hilo que parecen violar este principio, sospecho que el compilador de C# está realizando un análisis de las condiciones del ciclo que se puede reducir a una constante de tiempo de compilación . Si la constante se evalúa a true, entonces sabemos que el ciclo nunca terminará.

Por ejemplo, considere las dos funciones siguientes.

public bool NoError() 
{ 
    while (true) { } 
} 

public bool Error() 
{ 
    while (NoError()) { } 
} 

Como se demostró, la primera función no generará un error de tiempo de compilación. Sin embargo, el segundo será dado que el compilador no puede evaluar el resultado de la llamada de función NoError(). Este es también el caso si se modifica NoError() para devolver siempre true.

Cuestiones relacionadas