CA2200: следует повторно вызывать исключение для сохранения сведений о стеке

Свойство Значение
Идентификатор правила 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