在C#抛出异常时,它可能会有一个内部异常。我的目标是获取最内层的异常,或者换句话说,是没有内部异常的叶子异常。我可以使用while循环来实现:
while (e.InnerException != null)
{
e = e.InnerException;
}
但我想知道是否有一行代码可以做到这一点。
在C#抛出异常时,它可能会有一个内部异常。我的目标是获取最内层的异常,或者换句话说,是没有内部异常的叶子异常。我可以使用while循环来实现:
while (e.InnerException != null)
{
e = e.InnerException;
}
但我想知道是否有一行代码可以做到这一点。
public static class ExceptionExtensions
{
public static IEnumerable<T> innerExceptions<T>(this Exception ex)
where T : Exception
{
var rVal = new List<T>();
Action<Exception> lambda = null;
lambda = (x) =>
{
var xt = x as T;
if (xt != null)
rVal.Add(xt);
if (x.InnerException != null)
lambda(x.InnerException);
var ax = x as AggregateException;
if (ax != null)
{
foreach (var aix in ax.InnerExceptions)
lambda(aix);
}
};
lambda(ex);
return rVal;
}
}
catch (Exception ex)
{
var myExes = ex.innerExceptions<MyException>();
if (myExes.Any(x => x.Message.StartsWith("Encountered my specific error")))
{
// ...
}
}
Exception.GetBaseException()
是什么意思? - Kiquenet你可以通过两次调用 GetBaseException()
来实现另一种方式:
Exception innermostException = e.GetBaseException().GetBaseException();
AggregateException
,第一次调用会将您带到最内层的非AggregateException
,然后第二次调用会将您带到该异常的最内层异常。如果第一个异常不是AggregateException
,那么第二次调用只会返回相同的异常。AggregateException
没有合适的最内层异常,因为有多个“根本原因”异常(通常来自于聚合等待的单独任务)。AggregateException.GetBaseException()
返回的是AggregateException
本身,而不是底层异常。实际上,它自己的InnerException
仅仅是AggregateException.InnerExceptions.First()
。你能做的最好的事情就像这样:AggregateException.InnerExceptions.SelectMany(innerEx => innerEx.GetBaseException())
,以获取每个基本异常。他们都是平起平坐的。 - Josh Sutterfield
LibraryException -> LibraryException -> LibraryException -> MyException
。我的异常始终是链上的最后一个,并且没有自己的内部异常。 - Daniel T.