La différence entre re-lancer paramètre-moins de capture et de ne rien faire?

supposons que j'ai les deux classes suivantes dans deux assemblages différents:

//in assembly A
public class TypeA {
   // Constructor omitted
   public void MethodA
   {
     try {
       //do something
     }
     catch {
        throw;
     }
   }
}
//in assembly B
public class TypeB {
   public void MethodB
   {
     try {
       TypeA a = new TypeA();
       a.MethodA();
     }
     catch (Exception e)
       //Handle exception
     }
   }
}

dans ce cas, le try-catch dans MethodA élève juste l'exception mais ne le gère pas vraiment. Y a-t-il un avantage à utiliser la méthode "try-catch" dans MethodA? En d'autres termes, est-il une différence entre ce genre de bloc try-catch et ne pas l'utiliser du tout?

13
demandé sur JaredPar 2009-04-04 21:42:47
la source

11 ответов

Dans votre exemple, il n'y a aucun avantage à cela. Mais il y a des cas où il est souhaitable d'bouillonne une exception spécifique.

    public void Foo()
    {
        try
        {
            // Some service adapter code

            // A call to the service
        }
        catch (ServiceBoundaryException)
        {
            throw;
        }
        catch (Exception ex)
        {
            throw new AdapterBoundaryException("some message", ex);
        }
    }

cela vous permet d'identifier facilement la limite dans laquelle une exception s'est produite. Dans ce cas, vous devez vous assurer que vos exceptions aux limites ne sont lancées que pour le code spécifique à la limite.

7
répondu Mufaka 2009-04-04 22:14:40
la source

Oui il y a une différence. Lorsque vous attrapez une exception, .NET suppose que vous allez la gérer d'une manière ou d'une autre, la pile est déboulée jusqu'à la fonction qui fait la capture.

si vous ne l'attrapez pas, il finira comme une exception non contrôlée, ce qui fera appel à une sorte de diagnostic (comme un débogueur ou un enregistreur d'exception), la pile complète et son état au point réel de défaillance seront disponibles pour inspection.

donc si vous attrapez puis relancez une exception qui n'est pas traitée ailleurs vous dévalisez l'outil de diagnostic de l'information vraiment utile sur ce qui s'est réellement passé.

3
répondu AnthonyWJones 2009-04-04 21:51:53
la source

prise comme-est, la première option semblerait comme une mauvaise (ou devrait-elle être "inutile"?) idée. Toutefois, cela se fait rarement de cette façon. Les Exceptions sont généralement rejetées de l'intérieur d'un bloc de capture sous deux conditions:

A. Vous voulez vérifier l'exception générée pour les données et conditionnellement la bulle vers le haut de la pile.

try 
{
  //do something
}
catch (Exception ex)
{
  //Check ex for certain conditions.
  if (ex.Message = "Something bad")
    throw ex;
  else
    //Handle the exception here itself.
}

B. Une condition inacceptable s'est produite au sein d'une composante et cette information doit être communiquée à le code d'appel (généralement en ajoutant d'autres informations utiles ou en les enveloppant dans un autre type d'exception).

try 
{
  //do something
}
catch (StackOverflowException ex)
{
    //Bubble up the exception to calling code 
    //by wrapping it up in a custom exception.
    throw new MyEuphemisticException(ex, "Something not-so-good just happened!");
}
3
répondu Cerebrus 2009-04-04 22:15:00
la source

le simple fait de repenser n'a aucun sens - c'est la même chose que si vous n'aviez rien fait.

cependant il devient utile quand vous faites réellement quelque chose - la chose la plus commune est de log l'exception. Vous pouvez aussi changer l'état de votre classe, peu importe.

2
répondu Rashack 2009-04-04 21:48:55
la source

avec le code comme vous L'avez écrit pour Methota, il n'y a pas de différence. Tout ce qu'il fera, c'est manger les cycles du processeur. Cependant, il peut y avoir un avantage à écrire du code de cette façon s'il y a une ressource que vous devez libérer. Par exemple

Resource r = GetSomeResource();
try {
  // Do Something
} catch { 
  FreeSomeResource();
  throw;
}
FreeSomeResource();

cependant, il n'y a pas de raison de le faire de cette façon. Il serait beaucoup mieux d'utiliser un bloc finalà la place.

2
répondu JaredPar 2009-04-05 02:13:35
la source

ne fait jamais l'option A. Comme dit Anton, il mange la trace de la pile. L'exemple de JaredPar dévore aussi le stacktrace. Une meilleure solution serait:

SomeType* pValue = GetValue();
try {
  // Do Something
} finally {
  delete pValue;
}

si vous avez quelque chose en C# qui doit être publié, par exemple une FileStream vous avez les deux choix suivants:

FileStream stream;
try
{
  stream = new FileStream("C:\afile.txt");
  // do something with the stream
}
finally
{
  // Will always close the stream, even if there are an exception
  stream.Close(); 
}

ou plus proprement:

using (FileStream stream = new FileStream("c:\afile.txt"))
{
  // do something with the stream
}

L'utilisation de la déclaration permettra D'éliminer (et de fermer) le flux lorsqu'il est fait ou lorsqu'une exception est fermé.

1
répondu jgauffin 2009-04-04 21:55:51
la source

quand vous attrapez et lancez, il vous permet de définir un point de rupture sur la ligne throw .

1
répondu Rob Kennedy 2009-04-04 21:58:36
la source
Les exceptions de

peuvent être utilisées pour les regrouper en exceptions génériques... considérons l'exemple suivant.

public class XmlException: Exception{
   ....
} 

public class XmlParser{
   public void Parse()
   {
      try{
          ....
      }
      catch(IOException ex)
      {
         throw new XmlException("IO Error while Parsing", ex );
      }
   }
}

Cela donne l'avantage sur la catégorisation des exceptions. C'est ainsi que les gestionnaires de fichiers aspx et beaucoup d'autres codes système font l'encapsulation d'exception qui détermine leur chemin vers la pile et leur flux de logique.

1
répondu Akash Kava 2009-04-04 21:58:56
la source

L'assemblée A - try catch - bloc n'a pas de sens pour moi. Je crois que si vous ne vous occupez pas de l'exception, alors pourquoi attrapez-vous ces exceptions?. Il serait quand même jeté au niveau suivant.

mais, si vous créez une API de couche moyenne ou quelque chose comme ça et que gérer une exception ( et donc manger l'exception) dans cette couche n'a pas de sens, alors vous pouvez lancer votre propre couche ApplicationException. Mais certainement repenser la même exception n'a pas de sens.

1
répondu 123Developer 2009-04-04 23:47:16
la source

puisque les classes sont dans 2 assemblées différentes, vous pouvez vouloir o simplement attraper l'exception pour la journalisation il et puis le jeter à nouveau à l'appelant, de sorte qu'il peut le gérer comme il le juge bon. Un lancer au lieu d'un Lancer ex préservera l'information contextuelle sur l'origine de l'exception. Cela peut s'avérer utile lorsque votre assemblage est une API / framework où en vous ne devriez jamais avaler des exceptions à moins qu'il soit significatif de le faire, mais utile néanmoins dans le dépannage si il est enregistré par exemple dans L'EventLog.

1
répondu Abhijeet Patel 2009-04-05 01:58:19
la source

vous pouvez utiliser try{} catch(ex){} block dans la méthode a seulement si vous pouvez attraper l'exception spécifique qui peut être manipulée dans Methota() (par exemple: journalisation ).

une autre option est d'enchaîner l'exception en utilisant la propriété InnerException et de la transmettre à l'appelant. Cette idée ne tuera pas la trace de la pile.

0
répondu Shan 2016-02-05 12:10:45
la source

Autres questions sur