CA2200:再次引发以保留堆栈详细信息

属性
规则 ID CA2200
标题 再次引发以保留堆栈详细信息
类别 使用情况
修复是中断修复还是非中断修复 非中断
在 .NET 8 中默认启用 作为警告

原因

再次引发某个异常,在 throw 语句中显式指定该异常。

规则说明

引发异常后,它所包含的部分信息为堆栈跟踪。 堆栈跟踪是一个方法调用层次结构列表,它以引发异常的方法开头,以捕获异常的方法结尾。 如果通过在 throw 语句中指定异常来再次引发该异常,则将在当前方法处重启堆栈跟踪,并且引发该异常的原始方法与当前方法之间的方法调用列表将丢失。 若要保留原始堆栈跟踪信息和异常信息,请在未指定异常的情况下使用 throw 语句。

如果要从处理程序(catch 程序块)以外的某个位置再次引发异常,请在需要再次引发异常时使用 ExceptionDispatchInfo.Capture(Exception) 捕获处理程序中的异常以及 ExceptionDispatchInfo.Throw()。 有关详细信息,请参阅捕获异常以在之后再次引发异常

如何解决冲突

若要解决此规则的冲突,请在不显式指定异常的情况下再次引发异常。

何时禁止显示警告

不禁止显示此规则发出的警告。

示例

下面的示例演示了违反规则的 CatchAndRethrowExplicitly 方法和符合规则的 CatchAndRethrowImplicitly 方法。

class TestsRethrow
{
    static void Main2200()
    {
        TestsRethrow testRethrow = new TestsRethrow();
        testRethrow.CatchException();
    }

    void CatchException()
    {
        try
        {
            CatchAndRethrowExplicitly();
        }
        catch (ArithmeticException e)
        {
            Console.WriteLine("Explicitly specified:{0}{1}",
               Environment.NewLine, e.StackTrace);
        }

        try
        {
            CatchAndRethrowImplicitly();
        }
        catch (ArithmeticException e)
        {
            Console.WriteLine("{0}Implicitly specified:{0}{1}",
               Environment.NewLine, e.StackTrace);
        }
    }

    void CatchAndRethrowExplicitly()
    {
        try
        {
            ThrowException();
        }
        catch (ArithmeticException e)
        {
            // Violates the rule.
            throw e;
        }
    }

    void CatchAndRethrowImplicitly()
    {
        try
        {
            ThrowException();
        }
        catch (ArithmeticException)
        {
            // Satisfies the rule.
            throw;
        }
    }

    void ThrowException()
    {
        throw new ArithmeticException("illegal expression");
    }
}
Imports System

Namespace ca2200

    Class TestsRethrow

        Shared Sub Main2200()
            Dim testRethrow As New TestsRethrow()
            testRethrow.CatchException()
        End Sub

        Sub CatchException()

            Try
                CatchAndRethrowExplicitly()
            Catch e As ArithmeticException
                Console.WriteLine("Explicitly specified:{0}{1}",
               Environment.NewLine, e.StackTrace)
            End Try

            Try
                CatchAndRethrowImplicitly()
            Catch e As ArithmeticException
                Console.WriteLine("{0}Implicitly specified:{0}{1}",
               Environment.NewLine, e.StackTrace)
            End Try

        End Sub

        Sub CatchAndRethrowExplicitly()

            Try
                ThrowException()
            Catch e As ArithmeticException

                ' Violates the rule.
                Throw e
            End Try

        End Sub

        Sub CatchAndRethrowImplicitly()

            Try
                ThrowException()
            Catch e As ArithmeticException

                ' Satisfies the rule.
                Throw
            End Try

        End Sub

        Sub ThrowException()
            Throw New ArithmeticException("illegal expression")
        End Sub

    End Class

End Namespace