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


Не делайте лишних приведений

Обновлен: Ноябрь 2007

TypeName

DoNotCastUnnecessarily

CheckId

CA1800

Категория

Microsoft.Performance

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

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

Причина

Метод выполняет повторяющееся приведение одного из своих аргументов или локальных переменных. Для полного анализа данного правила проверяемая сборка должна быть построена с отладочной информацией и связанный PDB-файл должен быть доступен.

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

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

Если в языке C# перед фактическим выполнением приведения используется оператор is для проверки успешности такой операции, рассмотрите возможность проверки результата оператора as. Последний оператор предоставляет те же функциональные возможности, однако не выполняет неявную операцию приведения, как в случае оператора is.

Предотвращение нарушений

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

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

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

Пример

В следующем примере показан метод, который нарушает данное правило из-за использования оператора is языка C#. Во втором методе данное нарушение устранено за счет замены оператора is на проверку результата оператора as, который сокращает количество операций приведения в каждой итерации с двух до одной.

using System;
using System.Collections;
using System.Windows.Forms;

namespace PerformanceLibrary
{
   public sealed class SomeClass
   {
      private SomeClass() {}

      // This method violates the rule.
      public static void UnderPerforming(ArrayList list)
      {
         foreach(object obj in list) 
         {
            // The 'is' statement performs a cast operation.
            if(obj is Control) 
            {
               // The 'as' statement performs a duplicate cast operation.
               Control aControl = obj as Control;
               // Use aControl.
            }

         }
      }

      // This method satisfies the rule.
      public static void BetterPerforming(ArrayList list)
      {
         foreach(object obj in list) 
         {
            Control aControl = obj as Control;
            if(aControl != null) 
            {
               // Use aControl.
            }
         }
      }
   }
}

В следующем примере показан метод start_Click с несколькими повторяющимися операциями приведения, которые нарушают правило, и метод reset_Click, который удовлетворяет правилу благодаря сохранению результата приведения в локальной переменной.

Imports System
Imports System.Drawing
Imports System.Windows.Forms

Namespace PerformanceLibrary

   Public Class SomeForm : Inherits Form

      Dim start, reset As Button

      Sub New()

         start = New Button()
         reset = New Button()
         AddHandler start.Click, AddressOf start_Click
         AddHandler reset.Click, AddressOf reset_Click
         Controls.Add(start)
         Controls.Add(reset)

      End Sub

      ' This method violates the rule.
      Private Sub start_Click(sender As Object, e As EventArgs)

         Dim controlSize As Size = DirectCast(sender, Control).Size
         Dim rightToLeftValue As RightToLeft = _ 
            DirectCast(sender, Control).RightToLeft
         Dim parent As Control = DirectCast(sender, Control)

      End Sub

      ' This method satisfies the rule.
      Private Sub reset_Click(sender As Object, e As EventArgs)

         Dim someControl As Control = DirectCast(sender, Control)
         Dim controlSize As Size = someControl.Size
         Dim rightToLeftValue As RightToLeft = someControl.RightToLeft
         Dim parent As Control = someControl

      End Sub

   End Class

End Namespace
using System;
using System.Drawing;
using System.Windows.Forms;

namespace PerformanceLibrary
{
   public class SomeForm : Form
   {
      Button start, reset;

      public SomeForm()
      {
         start = new Button();
         reset = new Button();
         start.Click += new EventHandler(start_Click);
         reset.Click += new EventHandler(reset_Click);
         Controls.Add(start);
         Controls.Add(reset);
      }

      // This method violates the rule.
      void start_Click(object sender, EventArgs e)
      {
         Size controlSize = ((Control)sender).Size;
         RightToLeft rightToLeftValue = ((Control)sender).RightToLeft;
         Control parent = (Control)sender;
      }

      // This method satisfies the rule.
      void reset_Click(object sender, EventArgs e)
      {
         Control someControl = (Control)sender;
         Size controlSize = someControl.Size;
         RightToLeft rightToLeftValue = someControl.RightToLeft;
         Control parent = someControl;
      }
   }
}

См. также

Ссылки

as (Справочник по C#)

is (Справочник по C#)