CA1800: Non eseguire il cast inutilmente
TypeName |
DoNotCastUnnecessarily |
CheckId |
CA1800 |
Category |
Microsoft.Performance |
Breaking Change |
Non sostanziale |
Causa
Un metodo esegue cast duplicati su uno dei relativi argomenti o variabili locali. Affinché venga eseguita un'analisi completa tramite questa regola, l'assembly testato deve essere compilato con informazioni di debug e il file di database del programma associato (pdb) deve essere disponibile.
Descrizione della regola
I cast duplicati comportano una riduzione delle prestazioni, in particolare quando i cast vengono eseguiti in istruzioni di iterazione compatte. Per cast duplicati espliciti, archiviare il risultato del cast in una variabile locale e utilizzare la variabile locale anziché i cast duplicati.
Se si utilizza l'operatore C# is per verificare l'esito del cast prima che venga effettivamente eseguito, valutare se sia opportuno verificare in alternativa il risultato dell'operatore as. In questo modo viene fornita la stessa funzionalità senza che il cast implicito venga eseguito dall'operatore is.
Come correggere le violazioni
Per correggere una violazione di questa regola, modificare l'implementazione del metodo per ridurre al minimo il numero di cast.
Esclusione di avvisi
L'esclusione di un avviso da questa regola, così come dell'intera regola, è sicura se le prestazioni non costituiscono un problema.
Esempio
Nell'esempio riportato di seguito viene illustrato un metodo che viola la regola utilizzando l'operatore C# is. Un secondo metodo soddisfa la regola sostituendo l'operatore is con un test sul risultato dell'operatore as, il quale riduce il numero di cast per iterazione da due a uno.
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.
}
}
}
}
}
Nell'esempio riportato di seguito vengono illustrati il metodo start_Click con più cast espliciti duplicati che viola la regola e un metodo reset_Click che soddisfa la regola archiviando il cast in una variabile 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;
}
}
}