CA1800: 不必要にキャストしません
TypeName |
DoNotCastUnnecessarily |
CheckId |
CA1800 |
[カテゴリ] |
Microsoft.Performance |
互換性に影響する変更点 |
なし |
原因
メソッドで、引数またはローカル変数のいずれかについて二重のキャストを実行しました。この規則違反を完全に解析するには、テスト対象のアセンブリをデバッグ情報を使用してビルドします。また、関連するプログラム データベース (.pdb) ファイルを使用できるようにします。
規則の説明
二重のキャストがあるとパフォーマンスが低下します。特に、小さな繰り返しステートメントでキャストが実行される場合はそうです。明示的に二重のキャストが必要な場合、二重にキャストするのではなく、ローカル変数にキャストの結果を格納し、ローカル変数を使用します。
実際のキャストを実行する前に、C# の is 演算子を使用してキャストが成功するかどうかをテストしている場合、代わりに as 演算子の結果をテストすることをお勧めします。こうすると、is 演算子によって暗黙的にキャストが実行されず、同じ機能を実現できます。
違反の修正方法
この規則違反を修正するには、キャスト操作の数を最小限に抑えるようにメソッドの実装を変更します。
警告を抑制する状況
パフォーマンスが重要ではない場合は、この規則による警告を抑制するか、この規則を完全に無視しても安全です。
使用例
C# の is 演算子を使用して、この規則に違反するメソッドを次の例に示します。2 つ目のメソッドは、is 演算子を as 演算子の結果に対するテスト値で置き換えることで、この規則に適合しています。これによって、各繰り返しのキャスト操作の数が 2 つから 1 つに減ります。
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;
}
}
}