CA1800 : N'effectuez pas de cast inutilement

Élément Valeur
ID de la règle CA1800
Category Microsoft.Performance
Modification avec rupture Sans rupture

Cause

Une méthode effectue des casts en double sur l’un de ses arguments ou variables locales.

Il faut, pour une analyse complète selon cette règle, que l’assembly testé soit généré à l’aide d’informations de débogage et que le fichier de base de données de programme associé (.pdb) soit disponible.

Notes

Cette règle est déconseillée. Pour plus d’informations, consultez Règles dépréciées.

Description de la règle

Les casts en doublon font baisser les performances, surtout lorsque les casts sont exécutés au sein d'instructions d'itération compactes. Pour les opérations de cast en double explicites, stockez le résultat du cast dans une variable locale que vous utiliserez au lieu des opérations de cast en double.

Si l’opérateur C# is est utilisé pour savoir si le cast réussit avant que celui-ci ne soit réellement effectué, testez plutôt le résultat de l’opérateur as. Les fonctionnalités fournies sont les mêmes, sans l’opération de cast implicite effectuée par l’opérateur is. Vous pouvez également, dans C# 7.0 (et versions ultérieures), utiliser l’opérateur is avec critères spéciaux pour vérifier la conversion de type et caster l’expression en une variable de ce type en une seule étape.

Comment corriger les violations

Pour corriger une violation de cette règle, modifiez l’implémentation de la méthode de façon à réduire le nombre d’opérations de cast.

Quand supprimer les avertissements

Il est prudent, si les performances ne constituent pas un problème, de supprimer un avertissement de cette règle ou d’ignorer complètement cette dernière.

Exemples

L’exemple suivant montre une méthode qui enfreint la règle en utilisant l’opérateur C# is. Une deuxième méthode satisfait à la règle : elle remplace l’opérateur is par un test du résultat de l’opérateur as, ce qui réduit de deux à une le nombre d’opérations de cast par itération. La troisième méthode satisfait également à la règle, en ce qu’elle utilise is avec des critères spéciaux pour créer une variable du type souhaité si la conversion de type réussit.

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

L’exemple suivant montre une méthode start_Click, qui comporte plusieurs casts explicites en double et enfreint la règle, et une méthode reset_Click, qui satisfait à la règle en stockant le cast dans une variable locale.

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

Voir aussi