Trouver à l'intérieur de la plupart exception sans l'aide d'une boucle while?
Quand C# déclenche une exception, il peut avoir un intérieur d'exception. Ce que je veux faire est d'obtenir à l'intérieur de la plupart d'exception, ou en d'autres termes, la feuille d'exception qui n'a pas un intérieur d'exception. Je peux le faire dans une boucle while:
while (e.InnerException != null)
{
e = e.InnerException;
}
Mais je me demandais si il y avait quelques one-liner que je pourrais utiliser pour ce faire à la place.
- Je me suis levée d'une exception dans une de mes classes, mais ma classe est utilisé par une bibliothèque qui avale toutes les exceptions et jette sa propre. Le problème est, à l'exception de la bibliothèque est très générique et j'ai besoin de savoir qui d'exception, je l'ai jeté à savoir comment gérer le problème. Pour aggraver les choses, la bibliothèque va jeter son propre exception à plusieurs reprises imbriqués les uns dans les autres, à une profondeur arbitraire. Ainsi, par exemple, qu'il va jeter
LibraryException -> LibraryException -> LibraryException -> MyException
. Mon exception est toujours le dernier sur la chaîne, et ne dispose pas de son propre intérieur d'exception. - Oh, je comprends pourquoi vous pourriez étape vers le bas à l'intime, l'ayant fait moi-même (et ses variantes, comme la plus intime qui dérive d'un type particulier), mais je ne comprends pas ce qu'est la question avec ce que vous avez déjà.
- Oh, je vois ce que tu veux dire. Je me demandais juste si il y avait une autre façon de l'écrire. Je suis tellement habitué à l'utilisation de
LINQ
à faire à peu près tout ce qu'il me semble bizarre quand je dois écrire une boucle. Je travaille principalement avec les données d'accès donc j'ai assez bien travailler avecICollections
pour presque tout ce que je fais. - n'est-ce pas
LINQ
juste de masquer le fait que le code est essentiellement en boucle? Il n'existe aucun véritable base de jeu commandes .NET? - Oui,
LINQ
de cours utilise des boucles sous les couvertures, mais je n'ai pas à écrire qu'une partie de moi-même. Je préfère écrirelist.ForEach(Console.WriteLine)
queforeach (var item in list) { Console.WriteLine(item); }
. - Le plus de la réponse correcte est tapi dans le fond et (actuellement) seulement 2 votes -- Exception.GetBaseException(). Cela a été dans le cadre essentiellement pour toujours. Grâce à batCattle pour la santé mentale-case.
- stackoverflow.com/a/1456603/1135871 peut également être utile.
- Peut-être utile gist.github.com/benbrandt22/8676438
- Double Possible de la Bonne façon de gérer InnerException arbres?
Vous devez vous connecter pour publier un commentaire.
Oneliner 🙂
Évidemment, vous ne pouvez pas faire plus simple.
Comme dit dans cette réponse par Glenn McElhoe, c'est la seule façon fiable.
Exception.GetBaseException()
n'ai pas pour moi.Je crois
Exception.GetBaseException()
fait la même chose que ces solutions.Mise en garde: à Partir de diverses observations que nous avons compris qu'il n'est pas toujours littéralement faire la même chose, et dans certains cas, le récursive/itération solution à aller plus loin. Il est généralement les recoins les plus profonds de l'exception, qui est malheureusement incompatible, grâce à certains types d'Exceptions que de remplacer la valeur par défaut. Cependant si vous prenez certains types d'exceptions et de faire raisonnablement sûr qu'ils ne sont pas excentriques (comme AggregateException) alors je m'attends à ce qu'il obtient la légitime intime/première exception.
GetBaseException()
n'ai pas de retour de la première racine exception.ex.GetBaseException().GetBaseException().GetBaseException()
pour se rendre à l'deeptest exception.GetBaseException()
ne fonctionne pas pour moi, parce que la première exception est un AggregateException.Boucle dans InnerExceptions est la seule façon fiable.
Si l'exception interceptée est un AggregateException, puis
GetBaseException()
renvoie uniquement les plus intimes AggregateException.http://msdn.microsoft.com/en-us/library/system.aggregateexception.getbaseexception.aspx
Si vous ne savez pas à quelle profondeur l'intérieur des exceptions sont imbriquées, il n'y a pas moyen de contourner une boucle ou la récursivité.
Bien sûr, vous pouvez définir une méthode d'extension qui fait abstraction de cette suite:
Je sais que c'est un vieux post, mais je suis surpris que personne n'a suggéré
GetBaseException()
qui est une méthode de l'Exception
classe:Cela a été autour depuis .NET 1.1. La Documentation ici:
http://msdn.microsoft.com/en-us/library/system.exception.getbaseexception(v=vs. 71).aspx
Parfois, vous pourriez avoir de nombreuses exceptions internes (beaucoup de barbotage des exceptions).
Dans ce cas, vous pourriez faire:
Pas tout à fait une ligne, mais à proximité:
En fait est si simple, vous pouvez utiliser
Exception.GetBaseException()
Vous avez une boucle, et d'avoir à boucle, c'est plus propre pour déplacer la boucle dans une fonction séparée.
J'ai créé une méthode d'extension pour traiter cette question. Elle retourne une liste de toutes les exceptions internes du type spécifié, pourchassant Exception.InnerException et AggregateException.InnerExceptions.
Mon problème, pourchassant l'intérieur des exceptions a été plus compliqué que d'habitude, parce que les exceptions ont été lancés par les constructeurs des classes qui ont été invoqués par la réflexion. L'exception, nous ont été d'attraper eu un InnerException de type TargetInvocationException, et les exceptions dont nous avons réellement besoin de regarder ont été enfoui au plus profond dans l'arbre.
L'utilisation est assez simple. Si, par exemple, vous voulez savoir si nous avons rencontré un
Exception.GetBaseException()
?Vous pouvez utiliser la récursivité pour créer une méthode dans une classe utilitaire quelque part.
Utilisation:
L'extension de la méthode proposée (bonne idée @dtb)
Utilisation:
public static Exception GetOriginalException(this Exception ex) { if (ex.InnerException == null) return ex; return ex.InnerException.GetOriginalException(); }
AggregateException.InnerExceptions
?