Поделиться через


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

TypeName

RethrowToPreserveStackDetails

CheckId

CA2200

Категория

Microsoft.Usage

Критическое изменение

Не критическое

Причина

В операторе throw повторно вызывается и явным образом задается исключение.

Описание правила

После возникновения исключения часть содержащихся в нем данных становится трассировкой стека.Трассировка стека представляет собой список иерархий вызовов методов, который начинается с метода, создающего исключение и заканчивается методом, перехватывающим исключение.Если исключение было повторно вызвано за счет указания исключения в операторе throw, трассировка стека повторно запускается в текущем методе, а список вызовов методов между исходным методом, создавшим исключение, и текущим методом, будет утерян.Чтобы сохранить исходные сведения о трассировке стека с исключением, следует использовать оператор throw, не указывая исключение.

Устранение нарушений

Чтобы устранить нарушение данного правила, повторно вызовите исключение без его явного указания.

Отключение предупреждений

Для этого правила отключать вывод предупреждений не следует.

Пример

В следующем примере показан метод CatchAndRethrowExplicitly, нарушающий правило, и метод, CatchAndRethrowImplicitly, удовлетворяющий правилу.

Imports System

Namespace UsageLibrary

   Class TestsRethrow

      Shared Sub Main()
         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
using System;

namespace UsageLibrary
{
   class TestsRethrow
   {
      static void Main()
      {
         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 e)
         {
            // Satisfies the rule. 
            throw;
         }
      }

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