CA1800: Keine unnötigen Umwandlungen
TypeName |
DoNotCastUnnecessarily |
CheckId |
CA1800 |
Kategorie |
Microsoft.Performance |
Unterbrechende Änderung |
Nicht unterbrechend |
Ursache
Eine Methode führt doppelte Umwandlungen für eines ihrer Argumente oder eine ihrer lokalen Variablen aus. Damit eine umfassende Analyse gemäß dieser Regel möglich ist, muss die getestete Assembly mit Debuginformationen erstellt werden, und die zugehörige Programmdatenbankdatei (PDB) muss verfügbar sein.
Regelbeschreibung
Doppelte Umwandlungen beeinträchtigen die Leistung, insbesondere wenn die Umwandlungen in kompakten Iterationsanweisungen ausgeführt werden. Wenn explizite doppelte Umwandlungsoperationen durchgeführt werden müssen, sollte das Ergebnis der Umwandlung in einer lokalen Variablen gespeichert und die lokale Variable statt der doppelten Umwandlungsoperationen verwendet werden.
Wenn mit dem Operator is von C# getestet wird, ob die Umwandlung erfolgreich durchgeführt werden kann, bevor die eigentliche Umwandlung erfolgt, sollten Sie erwägen, stattdessen das Ergebnis des Operators as zu testen. Dieses Vorgehen bietet die gleiche Funktionalität ohne die implizite vom Operator is ausgeführte Umwandlungsoperation.
Behandeln von Verstößen
Sie beheben Verstöße gegen diese Regel, indem Sie die Methodenimplementierung so ändern, dass die Anzahl von Umwandlungsoperationen möglichst gering ist.
Wann sollten Warnungen unterdrückt werden?
Eine Warnung dieser Regel kann gefahrlos unterdrückt werden bzw. die Regel kann völlig ignoriert werden, wenn die Leistung nicht von Belang ist.
Beispiel
Im folgenden Beispiel wird eine Methode veranschaulicht, die den Operator is von C# verwendet und gegen die Regel verstößt. Eine zweite Methode verstößt nicht gegen die Regel, da der Operator is durch einen Test des Ergebnisses des Operators as ersetzt wird. Dadurch wird die Anzahl der Umwandlungsoperationen pro Iteration von zwei auf eins verringert.
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.
}
}
}
}
}
Im folgenden Beispiel werden zwei Methoden veranschaulicht: die Methode start_Click, die mehrere doppelte explizite Umwandlungen enthält und damit gegen die Regel verstößt, sowie die Methode reset_Click, die die Regel einhält, indem das Umwandlungsergebnis in einer lokalen Variablen gespeichert wird.
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;
}
}
}