Domanda

Ho notato qualcosa di strano in Visual Studio. Innanzitutto, prova a digitare questo (C #) da qualche parte in una funzione:

class Foo  
{  
    public void Bar()  
    {  
        string s;
        int i = s.Length;
    }
}

Ora, subito contrassegna s in s.Length come errore, dicendo " Uso di variabili locali non assegnate 's' " ;. D'altra parte, prova questo codice:

class Foo  
{  
    private string s;
    public void Bar()  
    {  
        int i = s.Length;
    }
}

Compilerà e sottolineerà s in stringa privata s con un avvertimento, dicendo " Il campo 'Foo.s' non è mai assegnato a, e avrà sempre il valore predefinito null " ;.

Ora, se VS è così intelligente e sa che s sarà sempre nullo, perché non è un errore ottenere la sua lunghezza nel secondo esempio? La mia ipotesi originale era, " Dà un errore di compilazione solo se il compilatore semplicemente non può completare il suo lavoro. Poiché il codice viene eseguito tecnicamente finché non si chiama mai Bar (), è solo un avvertimento. & Quot; Tranne che la spiegazione è invalidata dal primo esempio. Puoi comunque eseguire il codice senza errori purché non chiami mai Bar (). Quindi cosa dà? Solo una svista o mi sto perdendo qualcosa?

È stato utile?

Soluzione

Il primo esempio (l'errore) è un esempio di rilevamento dell'assegnazione definita e che viene applicato solo alle variabili locali. A causa del contesto limitato, il compilatore ha una stretta ermetica su questa situazione. Nota che s non è nullo, non è definito.

Nel secondo esempio, s è un campo (e il valore predefinito è null). Non si verifica alcun errore del compilatore, ma verrà sempre rilevato in fase di esecuzione. Questo caso particolare potrebbe essere intrappolato ma questo tipo di errore non è generalmente rilevabile dal compilatore.
Ad esempio, potresti aggiungere un metodo Bar2 () che assegna una stringa a s ma chiamarla più tardi di Bar () , oppure non in tutti. Ciò eliminerebbe l'avviso ma non l'errore di runtime.

Quindi è di progettazione.

Altri suggerimenti

Per il secondo esempio il codice è valido, potrebbe non funzionare correttamente. Ecco alcuni casi in cui questo programma potrebbe eseguire "correttamente"

  • Il compilatore non è corretto al 100%. È possibile per " s " avere un valore non nullo se un'istanza viene modificata tramite reflection.
  • Il programma può essere eseguito senza errori se il metodo Bar non viene mai chiamato
  • Questo programma potrebbe essere un programma di test che sta attivando un'eccezione NullReferenceException per motivi di test

L'unica ipotesi che posso fare è che nel secondo esempio, s potrebbe essere modificato tramite reflection (usando BindingFlags.Private per accedere al membro privato).

Nel primo esempio s è una variabile locale e il compilatore può facilmente verificare che la variabile s non sia stata assegnata prima di essere utilizzata.

Nella seconda, s è una variabile globale ed è possibile che sia stata inizializzata da qualche altra parte in una classe.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top