CA1800: Do not cast unnecessarily

Item Value
RuleId CA1800
Category Microsoft.Performance
Breaking change Non-breaking

Cause

A method performs duplicate casts on one of its arguments or local variables.

For complete analysis by this rule, the tested assembly must be built by using debugging information, and the associated program database (.pdb) file must be available.

Note

This rule has been deprecated. For more information, see Deprecated rules.

Rule description

Duplicate casts decrease performance, especially when the casts are performed in compact iteration statements. For explicit duplicate cast operations, store the result of the cast in a local variable and use the local variable instead of the duplicate cast operations.

If the C# is operator is used to test whether the cast will succeed before the actual cast is performed, consider testing the result of the as operator instead. This provides the same functionality without the implicit cast operation that is performed by the is operator. Or, in C# 7.0 and later, use the is operator with pattern matching to check the type conversion and cast the expression to a variable of that type in one step.

How to fix violations

To fix a violation of this rule, modify the method implementation to minimize the number of cast operations.

When to suppress warnings

It is safe to suppress a warning from this rule, or to ignore the rule completely, if performance is not a concern.

Examples

The following example shows a method that violates the rule by using the C# is operator. A second method satisfies the rule by replacing the is operator with a test against the result of the as operator, which decreases the number of cast operations per iteration from two to one. A third method also satisfies the rule by using is with pattern matching to create a variable of the desired type if the type conversion would succeed.

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

The following example shows a method, start_Click, that has multiple duplicate explicit casts, which violates the rule, and a method, reset_Click, which satisfies the rule by storing the cast in a local variable.

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

See also