Question

Si j'ai une méthode qui retourne quelque chose, comme

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

Ceci produit une erreur de compilation, évidemment parce que le bloc catch {} ne renvoie rien.

Ainsi, lorsque j'ai des méthodes avec des valeurs de retour, je n'utilise pas de bloc try-catch, ce qui est une mauvaise pratique. En cas d'erreur, j'aimerais définir une chaîne d'erreur correspondant à cette erreur. Mais alors j'ai besoin d'une valeur de retour aussi. Conseil?

Était-ce utile?

La solution

Stockez votre valeur de retour dans une variable temporaire comme celle-ci:

public DataTable ReturnSomething()
{
    DataTable returnValue = null;

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

    return returnValue;
}

Autres conseils

Vous devriez lever / lever l'exception dans votre bloc catch et la gérer dans la méthode d'appel.

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: Désolé pour toute erreur de syntaxe, je suis un peu rouillé en C #.

Vous devriez envelopper l'appelant d'un essai ... toutes les exceptions qui se produisent dans la routine appelée seront renvoyées à l'appelant et vous pourrez les intercepter ici.

Personnellement, je pense qu'il est excessif d'essayer cette routine car vous devriez laisser l'appelant gérer l'exception.

Pour mon exemple, cela serait codé comme suit ...

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

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

    // logic here
    return dt;
}

La variable ErrorString ressemble étrangement à une variable de code d'erreur. La pratique recommandée consiste à utiliser des exceptions pour transmettre directement les informations d'erreur, le cas échéant, plutôt que de stocker des éléments dans des codes d'erreur.

Vous faites effectivement la même chose avec votre chaîne ErrorString que si vous laissiez l'exception être interceptée par l'appelant: supprimer la responsabilité de répondre à une erreur de la méthode elle-même. C'est un bon objectif à avoir. Mais l'utilisation d'une chaîne d'erreur ne vous rapporte rien par rapport à l'utilisation d'une exception. En fait, vous perdez des informations de cette façon. Un certain nombre d'erreurs peuvent survenir, et bon nombre d'entre elles sont associées à des exceptions spéciales, avec leurs propres propriétés spéciales permettant de stocker des informations contextuelles sur l'échec. En enregistrant simplement le message dans une chaîne, vous perdez ces informations.

Donc, à moins que votre objectif ne soit spécifiquement de masquer le type d'erreur qui se produit chez l'appelant, vous ne pouvez que gagner en laissant passer l'exception.

Une autre chose à considérer est de savoir s’il s’agit vraiment d’un scénario d’erreur. Si c'est le cas, il est très peu probable que votre méthode d'appel se soucie de la valeur de retour. Dans ce cas, vous n'avez rien à craindre en laissant simplement l'exception et en ne renvoyant rien. Si ce n'est PAS vraiment un scénario d'erreur et que l'appelant va simplement continuer et faire autre chose, eh bien, c'est à l'appelant de décider, n'est-ce pas? Il n’ya toujours aucun avantage à obtenir en renvoyant une chaîne d’erreur et un DataTable factice ou une valeur null, en renvoyant l’exception avec toutes ses informations d’échec contextuelles.

Si vous envisagez d'utiliser l'option "Ne lancez pas de route d'exception". (ce que je ne recommande pas nécessairement), vous pouvez suivre l’approche TryParse utilisée par MS.

Quelque chose comme:

private string FillDataTable(out DataTable results)
{

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

}

}

Cela dépend de votre application. Vous pouvez retourner null , un DataTable vide ou ce qui convient dans certaines circonstances.

Je suppose que vous pouvez toujours définir le message, puis renvoyer null ou l'équivalent c # équivalent

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

Que diriez-vous de cela:

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;
}

Etant donné que vous cactez l'exception (et ne la lancez pas à nouveau) dans votre exemple, le code extérieur suppose que tout est correct et vous devez donc renvoyer quelque chose d'utile.

Si vous avez besoin de capturer l'exception là-bas et de faire quelque chose, tout va bien, mais s'il s'agit toujours d'une erreur, vous devez également la lancer, ou une exception différente, peut-être avec celle que vous venez de prendre en tant qu'InnerException.

Je pense que votre code est exécuté à un niveau suffisamment élevé de la pile d'appels et qu'il est mélangé avec du code d'interface utilisateur. Si tel est vraiment le cas, vous pouvez renvoyer null dans le bloc catch. Toutefois, si vous écrivez du code réutilisable, vous devez le refactoriser afin qu'il ne contienne pas de manipulation de l'interface utilisateur et ne gère pas l'exception à un niveau supérieur de la pile d'appels.

Vous pouvez le faire comme dans l'exemple de code ci-dessous.

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;
      }

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top