2010-02-22 14 views
13

Questa è solo una domanda "I am Curioso".C# - Come creare un loop infinito non rilevabile?

In C# -in approfondita Jon Skeet dice di espressioni lambda:
"se c'è un tipo di ritorno nonvoid ogni percorso di codice deve restituire un valore compatibile" (Pagina 233)

La nota dice poi:
"percorsi di codice generare eccezioni non hanno bisogno di restituire un valore, naturalmente, e nemmeno rilevabili loop infinito." (Pagina 233)

Mi chiedo cosa costituisca un loop infinito non rilevabile?

Questo può essere fatto solo dalla logica? o è fatto usando fattori esterni come un database o un file system?

+0

@JonSkeet forse può chiarire. –

risposta

21

Nei Jon si riferisce è descritto nella sezione 8.1 della specifica. Il compilatore in grado di rilevare solo molto semplici loop infiniti, come:

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

Il compilatore è abbastanza intelligente per capire che il ritorno non viene mai raggiunto, e quindi che il ciclo viene eseguito sempre. E 'legale, anche se folle, per dire:

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

perché se non v'è alcun percorso che restituisce un int, c'è anche alcun percorso che restituisce senza restituire un int!

Il compilatore non è abbastanza intelligente da trovare altri tipi di loop infiniti. Ad esempio:

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

Questo è chiaramente un ciclo infinito. Ma il compilatore non lo sa. Il compilatore dice "beh, forse c'è qualche valore di x dove x * 0 non è zero, quindi l'interruzione è raggiungibile, quindi questo non è un ciclo infinito". Tu e io sappiamo che questo è impossibile perché conosciamo la matematica, ma il compilatore no.

Leggere la sezione 8.1 se si desiderano i dettagli.

+3

In realtà non ricordo di aver scritto questo - il che suggerisce che la nota a piè di pagina è dovuta alla tua influenza :) –

+2

@Jon: Originariamente hai scritto "I percorsi di codice che generano eccezioni non hanno bisogno di restituire un valore, ovviamente". Ho notato che i loop infiniti rilevabili contano anche come punti finali irraggiungibili. –

+2

Giusto: sembra che ci sia un livello di dettaglio più probabile per ciascuno di noi :) –

3

È piuttosto banale creare un ciclo infinito utilizzando fonti esterne o anche strumenti abusivi come le interfacce.

Ad esempio:

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) 
     { 
      ; 
     } 
    } 

e quindi un semplice

Action action =() => DoStuff(new StaticNumber()); 
Problemi correlati