2012-05-15 9 views
9

Quando compilo il seguente programma in VS2010, VS2008 o MonoDevelop su Windows, ricevo l'avviso CS0219, "La variabile 'y' è assegnata ma il suo valore non è mai usato".Perché non viene fornito alcun avviso per questa variabile non utilizzata?

namespace Problem 
{ 
    public class Program 
    {   
     private static void Main(string[] args) 
     { 
      object x = new object(); 
      int y = 0; 
     } 
    } 
} 

Perché non c'è nessun avvertimento per x durante la compilazione in Visual Studio?

È interessante notare che, io capisco avvertimenti CS0219 per xey durante la compilazione in MonoDevelop su Mac OS X.

risposta

17

Risulta che questo avviso viene soppressa quando il destra-lato dell'operazione assegnazione non è una fase di compilazione costante.

Un post cancellato dal sito di feedback di Visual Studio di Microsoft ha spiegato che è perché hanno ricevuto molti reclami da persone che assegnavano variabili puramente in modo da poter vedere cosa restituiva una chiamata al metodo durante il debug e ha rilevato l'avviso irritante:

la soppressione del "assegnato, ma mai utilizzato" avviso in questo caso è stata motivata da un feedback da parte degli utenti che fanno questo:

int Blah(){ 
    // blah 
    BlahBlah(x, y, z) 
    // blah 
    // blah 
} 

"Ehi", dice l'utente durante il debug, "mi chiedo cos'è BlahBlah ritorno?«Ma non c'è modo semplice per esaminare il valore di ritorno nel debugger, così gli utenti molto spesso fanno questo:.

int Blah() 
{ 
    // blah 
    int temp = BlahBlah(x, y, z) 
    // blah 
    // blah 
} 

e quindi utilizzare la gente del posto o finestra di controllo per esaminare temperatura La temperatura è mai usato dovunque altro nella funzione, in modo che ha prodotto un fastidioso "cedute non leggere" warning

credo che questo sia un po 'un peccato dal momento che:.

  1. I in realtà trovare questi avvertimenti utili quando vengono dati in MonoDevelop.
  2. Chiunque può sopprimere l'avvertimento (ammesso che stiano sopprimendo anche quelli per le assegnazioni costanti in tempo di compilazione inutilizzate - forse dovrebbe esserci un avviso separato per quello?).

In ogni caso, capisco che non si può piacere a tutti.

+0

Ora che è possibile [visualizzare i valori di ritorno nel debugger di Visual Studio] (https://msdn.microsoft.com/en-us/library/dn323257.aspx), c'è ancora un motivo per disabilitare questo avviso? – cloudshao

+2

Un modo per riattivare l'avviso? – Xonatron

+1

Vengo qui a chiedere se qualcuno sa come riattivare l'avvertimento ... questo perché gli sviluppatori stanno iniziando variabili pesanti e non li usano (per pesante, intendo istanziare una classe che fa un sacco di cose quando non è necessario) –

2

potrei essere fuori qui, ma credo che sia perché y è impostata solo, mentre x è un'istanza a qualcosa di non banale - l'istanziazione potrebbe comportare azioni separate nel metodo New(), e poiché l'istanziazione della variabile potrebbe avere effetti collaterali, non è considerata inutilizzata. Nel tuo caso è solo un oggetto base(), quindi non c'è impatto, ma forse il compilatore non è abbastanza intelligente da distinguere.

Con y, d'altra parte, non vi sono effetti collaterali per l'istanziazione, quindi è considerato inutilizzato - il percorso del codice dell'applicazione sarebbe invariato se fosse stato rimosso completamente.

+1

Ma è possibile mantenere la chiamata 'new object()' senza assegnare il risultato a una variabile. – phoog

2

La mia impressione è che, essendo x un tipo di riferimento, il compilatore non mostra alcun avviso poiché il costruttore potrebbe eseguire alcune operazioni che potrebbero essere "significative"; al contrario, è un tipo di valore il cui valore viene solo assegnato ma mai usato, è facile per il compilatore dirti che non ha senso farlo se non vuoi fare un riferimento in linea.

+0

Questo ha senso, ma si potrebbe pensare che il compilatore sappia abbastanza per sapere che un oggetto di sistema come 'object' non avrà effetti collaterali. –

+1

@StevenBurnap il compilatore non è molto intelligente quando si tratta di informazioni "ovvie" come quella. In genere, ciò è dovuto al fatto che il vantaggio dell'aggiunta della logica per tenere traccia di tali elementi (piccolo) non supera il costo della maggiore complessità del compilatore (grande). – phoog

+0

Non sono convinto da questa risposta. Gli effetti dell'esecuzione del compilatore potevano essere così preservati: 'void Main (string [] args) {new object(); int y = 0; } '. – phoog

0

Eclipse considererà il caso non utilizzato.

1

Il resharper avviserà anche che x non è utilizzato.

0

Potrebbe essere che poiché x è un tipo di riferimento e pertanto è archiviato nell'heap, che impedirebbe la garbage collection di quell'oggetto fino a quando x non sarà incluso.

ad esempio:

void main(string[] args) 
{ 
    object x = new object(); 
    while (true) 
    { 
     // some threading stuff 
     // x is never garbage collected 
    } 
} 

In contrasto:

void main(string[] args) 
{ 
    new object(); 
    while (true) 
    { 
     // some threading stuff 
     // the unreferenced object IS garbage collected 
    } 
} 
+1

AFAIK che si applica solo se si sta eseguendo nel debugger, nel qual caso il runtime estende l'intervallo di vividezza dei locali all'intero metodo. Nella modalità di rilascio, possono essere molto più brevi - o in questo caso eliminati del tutto. –

Problemi correlati