CA1800 : N'effectuez pas de cast inutilement
TypeName |
DoNotCastUnnecessarily |
CheckId |
CA1800 |
Catégorie |
Microsoft.Performance |
Modification avec rupture |
Modification sans rupture |
Cause
Une méthode exécute des casts en doublon sur l'un de ses arguments ou l'une de ses variables locales.Pour l'analyse complète par cette règle, l'assembly testé doit être construit à l'aide des informations de débogage et le fichier de base de données de programme (.pdb) associé doit être disponible.
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 casts en doublon explicites, stockez le résultat du cast dans une variable locale et utilisez cette dernière en lieu et place des opérations de casts en doublon.
Si l'opérateur C# is est utilisé pour déterminer par test si le cast réussira avant son exécution proprement dite, vous pouvez plutôt envisager de tester le résultat de l'opérateur as.Ce procédé offre les mêmes fonctionnalités sans que l'opérateur is exécute le cast implicite.
Comment corriger les violations
Pour corriger une violation de cette règle, modifiez l'implémentation de la méthode pour réduire le nombre d'opérations de cast.
Quand supprimer les avertissements
Il est possible de supprimer sans risque un avertissement de cette règle, voire d'ignorer la règle, si les performances ne sont pas un problème.
Exemple
L'exemple suivant présente une méthode qui viole la règle à l'aide de l'opérateur C# is.Une seconde méthode satisfait la règle en remplaçant l'opérateur is par un test appliqué au résultat de l'opérateur as, procédé qui réduit le nombre d'opérations de cast par itération de deux à un.
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 présente une méthode, start_Click avec plusieurs casts explicites en doublon qui enfreignent la règle, et une méthode, reset_Click qui satisfait la règle en stockant le cast dans une variable locale.
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;
}
}
}