CA1800: не выполняйте лишних приведений

Товар Значение
Идентификатор правила CA1800
Категория Microsoft.Performance
Критическое изменение Не критическое

Причина

Метод выполняет повторяющиеся приведения к одному из его аргументов или локальных переменных.

Для полного анализа по этому правилу тестовая сборка должна быть создана с помощью сведений об отладке, а соответствующий файл базы данных программы (PDB) должен быть доступен.

Примечание.

Это правило устарело. Дополнительные сведения см. в разделе "Устаревшие правила".

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

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

Если оператор C# is используется для проверки успешности приведения перед выполнением фактического as приведения, попробуйте проверить результат оператора. Это обеспечивает ту же функциональность без неявной операции приведения, выполняемой оператором is . Кроме того, в C# 7.0 и более поздних версиях используйте is оператор с сопоставлением шаблонов для проверка преобразования типов и приведения выражения к переменной этого типа на одном шаге.

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

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

Когда лучше отключить предупреждения

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

Примеры

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

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который удовлетворяет правилу, сохраняя приведение в локальной переменной.

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;
      }
   }
}

См. также