Domanda

Se ho un metodo che restituisce qualcosa, come

public DataTable ReturnSomething()
{
   try
   {  
      //logic here
     return ds.Tables[0];
   }
   catch (Exception e)
   {
      ErrorString=e.Message;
   }
}

Questo produce un errore del compilatore, ovviamente perché il blocco catch {} non restituisce nulla.

Quindi quando ho metodi con valori di ritorno non uso il blocco try-catch, che è una cattiva pratica. Se c'è un errore, vorrei impostare la stringa di errore su quell'errore. Ma poi ho bisogno anche di un valore di ritorno. Consigli?

È stato utile?

Soluzione

Memorizza il tuo valore di ritorno in una variabile temporanea come questa:

public DataTable ReturnSomething()
{
    DataTable returnValue = null;

    try
    {
        //logic here
        returnValue = ds.Tables[0]; 
    }
    catch (Exception e)
    {
        ErrorString=e.Message;
    }

    return returnValue;
}

Altri suggerimenti

Dovresti sollevare / lanciare l'eccezione nel tuo blocco catch e gestirlo nel metodo di chiamata.

public void invokeFaultyCode()
{
    try
    {
        DataTable dt = ReturnSomething();
    }
    catch(Exception e)
    {
        // Print the error message, cleanup, whatever
    }    
}
public DataTable ReturnSomething() throws Exception
{
   try
   {  
      //logic here
     return ds.Tables[0];
   }
   catch (Exception e)
   {
      ErrorString=e.Message;
      throw;
   }
}

PS: mi dispiace per qualsiasi errore di sintassi, sono un po 'arrugginito su C #.

Dovresti avvolgere il chiamante con un tentativo di intercettazione ... tutte le eccezioni che si verificano nella routine chiamata verranno espulse dal chiamante e potrai prenderle lì.

Personalmente, penso che sia eccessivo provare a catturare questa routine poiché dovresti fare in modo che il chiamante gestisca l'eccezione.

Per il mio esempio, questo sarebbe codificato come segue ...

private void DoSomething() {
    try {
        DataTable dt = ReturnSomething();
    }
    catch (Exception ex) {
    }    
}

public DataTable ReturnSomething() {
    DataTable dt = new DataTable();

    // logic here
    return dt;
}

La variabile ErrorString appare sospettosamente come una variabile del codice di errore. La pratica raccomandata è quella di utilizzare le eccezioni per trasferire direttamente le informazioni sugli errori, ove necessario, anziché archiviare le cose nei codici di errore.

Stai effettivamente facendo la stessa cosa con ErrorString come faresti se lasci che l'eccezione venga colta dal chiamante: rimuovere la responsabilità di rispondere a un errore dal metodo stesso. Questo è un buon obiettivo da avere. Ma l'uso di una stringa di errore non ti fa guadagnare nulla rispetto all'uso di un'eccezione. In effetti, perdi informazioni in questo modo. Esistono numerosi tipi di errori che possono verificarsi e molti hanno eccezioni speciali associate, con le loro proprietà speciali per contenere informazioni contestuali sull'errore. Memorizzando semplicemente il messaggio in una stringa, stai perdendo queste informazioni.

Quindi, a meno che il tuo obiettivo non sia specificamente quello di nascondere il tipo di errore che si sta verificando dal chiamante, puoi ottenere solo lasciando passare l'eccezione.

Un'altra cosa da considerare è se questo è veramente uno scenario di errore. Se lo è, è molto improbabile che il tuo metodo di chiamata si prenda cura del valore restituito. In tal caso, non hai nulla di cui preoccuparti lasciando semplicemente andare l'eccezione e non restituendo nulla. Se NON è davvero uno scenario di errore, e il chiamante continuerà e farà qualcos'altro, beh, questo è per il chiamante che decide, giusto? Non c'è ancora molto vantaggio da ottenere restituendo una stringa di errore e una DataTable fittizia o un valore null, oltre a generare l'eccezione con tutte le informazioni contestuali sull'errore.

Se hai intenzione di dirigere il " non lanciare una rotta di eccezione " (che non raccomando necessariamente), potresti seguire l'approccio TryParse che MS utilizza.

Qualcosa del tipo:

private string FillDataTable(out DataTable results)
{

  try
{
  results = new DataTable(); //something like this;
  return String.Empty;
}
catch (Exception ex)
{
  results = null;
 return ex.Message;

}

}

Dipende dalla tua applicazione. Puoi restituire null , un DataTable vuoto o qualunque cosa sia adatta in circostanze.

Suppongo che tu possa ancora impostare il messaggio, quindi restituire null o qualunque sia l'equivalente c #

public DataTable ReturnSomething(){ 
   try {
        //logic here 
        return ds.Tables[0]; 
   } catch (Exception e) {
        ErrorString=e.Message;
        return null;
   }
}

Che ne dici di questo:

public DataTable ReturnSomething(out string errorString)
{
   errorString = string.Empty;
   DataTable dt = new DataTable();
   try
   {  
      //logic here
     dt = ds.Tables[0];
   }
   catch (Exception e)
   {
      errorString = e.Message;
   }
   return dt;
}

Dato che stai cercando l'eccezione (e non la butti di nuovo) nel tuo esempio, il codice esterno presuppone che tutto sia a posto e che quindi dovresti restituire qualcosa di utile.

Se devi catturare l'eccezione lì e fare qualcosa che va bene, ma se è ancora un caso di errore dovresti anche lanciarlo, o un'eccezione diversa, forse con quella che hai appena catturato come InnerException.

Penso che il tuo codice venga eseguito a un livello sufficientemente alto dello stack di chiamate ed è miscelato con il codice dell'interfaccia utente. In tal caso, è possibile restituire null nel blocco catch. Tuttavia, se stai scrivendo codice riutilizzabile, dovresti rifattorizzarlo in modo che non contenga manipolazioni dell'interfaccia utente e gestire l'eccezione a un livello superiore nello stack di chiamate.

Puoi farlo come il seguente codice di esempio.

public DataTable ReturnSomething(out string OutputDesc)
{
   try
      {
         //logic here
         OutputDesc = string.Format("Your Successful Message Here...");
         return ds.Tables[0];
      }
      catch (Exception e)
      {
         OutputDesc =e.Message;
         return null;
      }

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