Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 找到最内部异常的正确方法?_C#_Exception_Exception Handling - Fatal编程技术网

C# 找到最内部异常的正确方法?

C# 找到最内部异常的正确方法?,c#,exception,exception-handling,C#,Exception,Exception Handling,我正在处理一些类,这些类在抛出时具有相对较深的InnerException树。我想记录最内部的异常并对其采取行动,该异常才是问题的真正原因 我目前正在使用类似于 public static Exception getInnermostException(Exception e) { while (e.InnerException != null) { e = e.InnerException; } return e; } 这是处理异常树的正确方法吗?总之

我正在处理一些类,这些类在抛出时具有相对较深的InnerException树。我想记录最内部的异常并对其采取行动,该异常才是问题的真正原因

我目前正在使用类似于

public static Exception getInnermostException(Exception e) {
    while (e.InnerException != null) {
        e = e.InnerException;
    }
    return e;
}

这是处理异常树的正确方法吗?

总之,是的。我想不出任何明显更好或不同的方法。除非您想将其添加为扩展方法,但实际上它是一个六个,另一个六个。

您可以使用该方法。 非常简单的例子:

try
{
    try
    {
        throw new ArgumentException("Innermost exception");
    }
    catch (Exception ex)
    {
        throw new Exception("Wrapper 1",ex);
    }
}
catch (Exception ex)
{
    // Writes out the ArgumentException details
    Console.WriteLine(ex.GetBaseException().ToString());
}

我认为您可以使用以下代码获得最内部的异常:

public static Exception getInnermostException(Exception e) { 
    return e.GetBaseException(); 
}

有些异常可能有多个根本原因(例如,
aggregateeexception
ReflectionTypeLoadException

我创建了自己的导航树,然后不同的访问者要么收集所有的东西,要么只收集根本原因。样本输出。下面是相关的代码片段

public void Accept(ExceptionVisitor visitor)
{
    Read(this.exception, visitor);
}

private static void Read(Exception ex, ExceptionVisitor visitor)
{
    bool isRoot = ex.InnerException == null;
    if (isRoot)
    {
        visitor.VisitRootCause(ex);
    }

    visitor.Visit(ex);
    visitor.Depth++;

    bool isAggregateException = TestComplexExceptionType<AggregateException>(ex, visitor, aggregateException => aggregateException.InnerExceptions);
    TestComplexExceptionType<ReflectionTypeLoadException>(ex, visitor, reflectionTypeLoadException => reflectionTypeLoadException.LoaderExceptions);

    // aggregate exceptions populate the first element from InnerExceptions, so no need to revisit
    if (!isRoot && !isAggregateException)
    {
        visitor.VisitInnerException(ex.InnerException);
        Read(ex.InnerException, visitor);
    }

    // set the depth back to current context
    visitor.Depth--;
}

private static bool TestComplexExceptionType<T>(Exception ex, ExceptionVisitor visitor, Func<T, IEnumerable<Exception>> siblingEnumerator) where T : Exception
{
    var complexException = ex as T;
    if (complexException == null)
    {
        return false;
    }

    visitor.VisitComplexException(ex);

    foreach (Exception sibling in siblingEnumerator.Invoke(complexException))
    {
        visitor.VisitSiblingInnerException(sibling);
        Read(sibling, visitor);
    }

    return true;
}
公共作废接受(例外访问者)
{
阅读(本条例外,访客);
}
私有静态无效读取(异常示例,异常访问者)
{
bool isRoot=ex.InnerException==null;
if(isRoot)
{
访客办公室(ex);
}
访客参观(ex);
visitor.Depth++;
bool isAggregateException=TestComplexExceptionType(例如,visitor,aggregateException=>aggregateException.InnerExceptions);
TestComplexeExceptionType(例如,访问者,reflectionTypeLoadException=>reflectionTypeLoadException.LoaderExceptions);
//聚合异常从InnerExceptions填充第一个元素,因此无需重新访问
如果(!isRoot&&!isAggregateException)
{
visitor.VisitInnerException(例如InnerException);
读取(例如InnerException,访问者);
}
//将深度设置回当前上下文
参观者:深度--;
}
私有静态bool testcomplexexExceptionType(Exception ex,ExceptionVisitor,Func siblingEnumerator),其中T:Exception
{
var complexException=ex as T;
if(complexException==null)
{
返回false;
}
visitor.VisitComplexException(ex);
foreach(siblingEnumerator.Invoke中的异常同级(complexException))
{
visitor.VisitSiblingInnerException(兄弟姐妹);
阅读(兄弟姐妹、访客);
}
返回true;
}

+1,我更喜欢另一个答案,因此我接受了它。这很公平,无可争辩:)我想我应该给出一些示例代码/测试工具来演示它的实际效果。如果有任何重复,可能是另一个重复,这一个年龄较大,答案正确。问题年龄并不总是指定重复的主要标准。例如,考虑到另一个问题的数量是这个问题的十倍以上。而且,被接受的答案只反映了提问者的意见。最后,请注意,到另一个问题的链接也提供了
GetBaseException()
,但随后指出了它在某些情况下的限制。当存在重复链接时,视图的数量是没有意义的。可能是因为标题的措辞,所以我编辑了标题。不管怎样,只要标记它,并让社区在需要时修复它。有关用于关闭重复项的条件,请参阅和。顺便说一句,重复的问题可能非常有价值,因为它们可以引导人们找到感兴趣的话题,而这些人可能会选择一些不同的途径来找到感兴趣的话题。而一个以重复形式结束的问题仍然可以获得(或下降)选票和评论。这也适用于它的答案。