No convertir innecesariamente
Actualización: noviembre 2007
Nombre de tipo |
DoNotCastUnnecessarily |
Identificador de comprobación |
CA1800 |
Categoría |
Microsoft.Performance |
Cambio problemático |
No problemático |
Motivo
Un método realiza conversiones de tipos duplicadas en uno de sus argumentos o variables locales. Para obtener un análisis completo utilizando esta regla, el ensamblado probado se debe generar con información de depuración y el archivo de base de datos de programa asociado (.pdb) debe estar disponible.
Descripción de la regla
Las conversiones de tipos duplicadas reducen el rendimiento, sobre todo cuando las conversiones de tipos se realizan en instrucciones de iteración compactas. Para obtener conversiones de tipos duplicadas de forma explícita, almacene el resultado de la conversión en una variable local y utilícela en lugar de las operaciones de conversión de tipos duplicadas.
Si el operador is de C# se utiliza para comprobar si la conversión se ha realizado correctamente antes de realizar la conversión actual, considere comprobar el resultado del operador as en su lugar. Esto proporciona la misma funcionalidad sin la operación de conversión implícita realizada por el operador is.
Cómo corregir infracciones
Para corregir una infracción de esta regla, modifique la implementación del método para minimizar el número de operaciones de la conversión de tipos.
Cuándo suprimir advertencias
Es seguro suprimir una advertencia de esta regla, u omitir completamente la regla, si el rendimiento no es importante.
Ejemplo
El ejemplo siguiente muestra un método que infringe la regla mediante el operador is de C#. Un segundo método cumple la regla reemplazando el operador is con una comparación con el resultado del operador as, que disminuye el número de operaciones de conversión por iteración de dos a una.
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.
}
}
}
}
}
El ejemplo siguiente muestra un método, start_Click, con múltiples conversiones de tipos explícitas duplicadas, que infringe la regla, y un método, reset_Click, que cumple la regla almacenando la conversión en una variable local.
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;
}
}
}