2011-12-21 15 views
5

avere questo codice, non capisco perché se l'assegnazione di una variabile in un blocco finally non si capisce che sarà SEMPRE assegnata. Penso di perdere un'opzione valida in cui la valuta non verrà assegnata. Se lo sai, sarà bello capire perché. lo apprezzo molto!Uso della variabile locale non assegnata. Ma rientra sempre nel compito

Grazie!

CurrencyVO currency; 

try 
{ 
    if (idConnection.HasValue && idConnection != 0) 
    { 
     currencyConnection = client.GetConnection(idConnection.Value); 
     model.Connection = currencyConnection; 
    } 
    else 
    { 
     int providerUserKey = (int)Models.UserModel.GetUser().ProviderUserKey; 
     currencyConnection = client.GetConnection(providerUserKey); 
    }       
    currency = model.Currencies.SingleOrDefault(c => c.IdCountry == currencyConnection.idcountry) ?? new CurrencyVO();  
} 
catch 
{ 
     currency = new CurrencyVO();      
} 
finally 
{ 
     model.PublishedContainer.Currency = currency; 
} 

l'errore si verifica sul blocco finally. Se lo tolgo dal blocco finally in questo modo:

   } catch { 
        currency = new CurrencyVO(); 
       } 
       model.PublishedContainer.Currency = currency; 

funziona correttamente.

+1

Yoy dovrebbe indicare questo post come una domanda – jclozano

+0

Sostituzione dell'ultima riga del blocco Try con "currency = new CurrencyVO();" lo fa non errore, vero? – UnhandledExcepSean

+0

@SpectralGhost: nulla all'interno del blocco 'try' cambierà l'errore - è necessario assegnare' currency' prima del blocco 'try' (anche se si assegna semplicemente' null'). –

risposta

8

L'assegnazione definitiva di monitoraggio che il compilatore C# effettua doesn' t necessariamente eseguire un'analisi completa (che non sarebbe possibile nel caso generale) - ci sono regole che limitano la complessità di un'analisi Eseguiremo. La regola che copre il blocco finally qui è documentata in http://msdn.microsoft.com/en-us/library/aa691181.aspx:

Per un'istruzione try stmt della forma:

trytry-blockfinallyinfine blocco

  • Lo stato preciso di assegnazione di v all'inizio di try-block è lo stesso dello stato di assegnazione definito di v allo inizio stmt.
  • Lo stato di assegnazione definito di v all'inizio del infine blocco è lo stesso come lo stato di assegnazione definito di v al all'inizio di stmt.
  • ...

Quindi per la vostra esempio particolare, dal momento che non è sicuramente currency assegnato all'inizio del blocco try, si ritiene di non essere definitivamente assegnato all'inizio del blocco finally.

+1

Mi hai battuto mentre stavo testando il codice :) Nell'esempio precedente, se il costruttore di CurrencyVO ha lanciato un'eccezione, l'esecuzione avrebbe colpito il blocco finale con valuta ancora indefinita. – TheEvilPenguin

0

Si sta creando un nuovo oggetto CurrencyVO all'interno del blocco catch: che verrà eseguito solo in caso di errore/eccezione. Pertanto, se non si riscontrano eccezioni: la variabile currency non verrà assegnata. Ecco perché non puoi usarlo.

edit: apportare le seguenti modifiche per il codice per la compilazione:

CurrencyVO currency = null; 

e infine:

if (currency != null) 
    model.PublishedContainer.Currency = currency; 

http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/a994a0ff-432b-4d23-b7d2-838b0b961de0

+0

La valuta è assegnata nell'ultima riga del tentativo – Joe

+0

@Joe: true, l'ho notato più tardi ma suppongo che il compilatore non possa garantire che quell'assegnazione verrà eseguita e per questo motivo non consente l'uso della variabile – olegvs

+0

Realmente? Sembra che verrà assegnato nel tentativo o cattura. Uno deve essere catturato, giusto? – Joe

1

Cosa succede se new CurrencyVO() causa un'eccezione nel blocco catch? A-ha!

+0

bello. Lascio l'accettato alla risposta più formale, ma questa era "intelligente". +1 –

1

Si può ragionare senza applicare le specifiche della lingua. La modalità di errore qui è che l'istruzione nel blocco catch può generare un'eccezione. Piuttosto possibile, lanciare un'eccezione in un costruttore è supportata in C#. Ma in generale, qualsiasi affermazione può generare un'eccezione. Che lascerà la variabile non inizializzata. Il compito nel blocco finally verrà sempre eseguito. E usa una variabile non inizializzata in quel caso.

Avrai bisogno di pensare a ciò che devi accadere in quel caso, se è del tutto pertinente. Ma la soluzione ovvia è semplicemente inizializzare la variabile in modo esplicito.

Problemi correlati