Domanda

Si consideri,

        static void Main(string[] args)
        {
            Console.WriteLine(fun());
        }

        static int fun()
        {
            int i = 0;
            try
            {
                i = 1;
                return i;
            }
            catch (Exception ex)
            {
                i = 2;
                return i;
            }
            finally
            {
                i = 3;
            }
        }

Il codice di esempio genera " 1 " ;. ma il valore di i viene modificato in 3 nel blocco infine. Perché il valore di 'i' non è stato cambiato in 3?

Grazie

È stato utile?

Soluzione

Considera questo codice. Penso che il codice spieghi cosa stai pensando e come puoi far accadere ciò che pensi dovrebbe accadere realmente:

static void Main(string[] args)
{
    int counter = 0;
    Console.WriteLine(fun(ref counter)); // Prints 1
    Console.WriteLine(counter); // Prints 3
}        

static int fun(ref int counter)
{
  try
  {
      counter = 1;
      return counter;
  }
  finally
  {
      counter = 3;
  }
}

Con questo codice si restituisce 1 dal metodo, ma si imposta anche la variabile contatore su 3, a cui è possibile accedere dall'esterno del metodo.

Altri suggerimenti

Devi ricordare che alla fine viene eseguito dopo tutto il resto nel tentativo di catturare. Inserisci l'istruzione return dopo l'istruzione try / catch / finally per farla restituire 3.

Immagino che se usi un tipo di riferimento anziché un tipo di valore otterrai un comportamento diverso.

Quando hai detto " return i " ... C # inserisce quel valore di ritorno in un'area di mantenimento temporanea (memoria) e quindi esegue il tuo codice "finally" ... se il blocco finally è stato in grado di modificare quel valore, esso sconfiggerebbe la sicurezza / finalismo del blocco finally.

È come un'istruzione using con un ritorno all'interno ... il " Dispose " sta ancora per succedere, DOPO il ritorno (per così dire).

Infine viene sempre eseguito

Il tuo codice viene sempre eseguito alla fine, indipendentemente dal fatto che sia stata generata un'eccezione o meno. Quindi il tuo codice dovrebbe effettivamente essere:

try
{
    i = 1;
}
catch
{
    i = 2;
}
finally
{
    i = 3;
}
return i;

Ma in questo banale caso finalmente il blocco non avrà molto senso. Perché restituiremo sempre 3, non importa cosa sia successo prima.

Infine viene utilizzato per rilasciare risorse

Il blocco

finalmente dovrebbe normalmente essere usato quando devi liberare alcune risorse di sistema allocate all'interno del blocco try (es. apertura di una connessione DB e lettura dei dati in try e chiudendolo in finalmente ). Quindi verranno sempre rilasciati, indipendentemente dal fatto che ci sia un'eccezione o meno. In questo caso non ha molto senso usare il blocco finalmente .

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