避免进行不必要的强制转换
更新:2007 年 11 月
TypeName |
DoNotCastUnnecessarily |
CheckId |
CA1800 |
类别 |
Microsoft.Performance |
是否重大更改 |
否 |
原因
某方法对其参数或局部变量之一执行重复的强制转换。要通过该规则进行全面分析,必须使用调试信息生成被测试的程序集,并且关联的程序数据库 (.pdb) 文件必须可用。
规则说明
重复强制转换会降低性能,特别是在精简的迭代语句中执行强制转换时。对于显式重复强制转换操作,将强制转换的结果存储在局部变量中,并使用局部变量来替代重复强制转换操作。
如果在执行实际的强制转换之前,使用 C# is 运算符来测试强制转换是否将成功,请考虑转为测试 as 运算符的结果。后者可以提供相同的功能,但不需要由 is 运算符执行的隐式强制转换操作。
如何修复冲突
要修复与该规则的冲突,请修改方法实现,以最大限度地减少强制转换操作的次数。
何时禁止显示警告
如果无需顾虑性能,则可以安全地禁止显示此规则发出的警告,或者完全忽略此规则。
示例
下面的示例演示一个使用 C# is 运算符的与规则冲突的方法。第二个方法将 is 运算符替换为针对 as 运算符的结果进行的测试(该测试将每个迭代的强制转换操作的次数从两次减少为一次),从而满足该规则。
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.
}
}
}
}
}
下面的示例演示一个与规则冲突的方法 start_Click(多次重复执行显式强制转换)和一个满足规则的方法 reset_Click(将强制转换存储在局部变量中)。
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;
}
}
}