2009-12-23 2 views
8

In C#, il seguente metodo non verrà compilato:Perché il compilatore si comporta diversamente con questo codice?

public bool IsItTrue() 
{ 
} 

Gli errori del compilatore: 'IsItTrue()': non tutti i percorsi di codice restituiscono un valore, che ha perfettamente senso. Ma la seguente compilazione senza alcun problema.

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

Quale sembra errato come nessuna dichiarazione di ritorno. Perché è così? Qualsiasi aiuto qui ...,

risposta

13

Il compilatore sa che il secondo metodo non tornerà mai più.

Se uno dei due metodo restituisce mai in nessun caso allora devono restituire un bool.

Il primo metodo non contiene loop infiniti, non genera eccezioni incondizionate ecc., Pertanto deve restituire un valore bool. Il codice non restituisce un bool, quindi il compilatore rifiuta di compilarlo.

Il secondo metodo non ritorna mai a causa della infinita while (true) loop. Se mai ritorna allora non importa che cosa (se mai) è mai restituito in modo che il compilatore permetterà di compilare.

Un paio di esempi che il compilatore riconoscerà e permettere:

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

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

piccola spiegazione per favore .., – Dhana

+0

Interessante il fatto che il compilatore avrebbe permesso questo.Posso capire perché * potrebbe * essere permesso, ma mi chiedo quale sia lo scopo della vita reale che serve. –

+0

So che potremmo volere qualcosa di simile ad un tempo (vero) per un thread ma anche un thread dovrebbe finire ad un certo punto? Quindi, se il compilatore può rilevare una situazione del genere, perché non lancia un punto di errore in un ciclo infinito? – uriDium

3

Il primo è spiegato bene dal messaggio di errore del compilatore.

Il secondo mai restituisce, quindi non c'è mai alcun valore restituito.

Non è lo stesso. Nel tuo primo esempio il metodo potrebbe tornare senza dare alcun valore al chiamante -> Errore del compilatore.

La seconda non potrà mai tornare (il compilatore è abbastanza intelligente per questo, si capisce che si è creato un ciclo infinito). Non entrerà mai nello stato "Va bene, ho raggiunto la fine del metodo e non so cosa restituire".

1

Le Halting Problem afferma che non si può in genere determinare se un programma terminerà o correre per sempre. Dato che ci sono esempi in questo thread che sembrano violare questo principio, sospetto che il compilatore C# stia eseguendo analisi sulle condizioni del ciclo che possono essere ridotte a una costante di tempo di compilazione . Se la costante viene valutata a true, allora sappiamo che il ciclo non terminerà mai.

Ad esempio, considerare le seguenti due funzioni.

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

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

Come dimostrato, la prima funzione non genererà un errore di tempo di compilazione. Tuttavia, la seconda volontà dal momento che il compilatore non può valutare il risultato della chiamata di funzione NoError(). Questo è anche il caso se NoError() viene modificato per restituire sempre true.