避免进行不必要的强制转换

by Lancer 29. July 2009 09:12
Visual Studio Team System
避免进行不必要的强制转换

更新: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(将强制转换存储在局部变量中)。

Visual Basic
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;
      }
   }
}
 

Tags:

代码检查 | 技术文章

使用字符串长度测试是否有空字符串

by Lancer 15. July 2009 17:00
Visual Studio Team System
使用字符串长度测试是否有空字符串

 

更新:2007 年 11 月

TypeName

TestForEmptyStringsUsingStringLength

CheckId

CA1820

类别

Microsoft.Performance

是否重大更改

将字符串与空字符串比较时使用的是 Object..::.Equals

使用 String..::.Length 属性或 String..::.IsNullOrEmpty 方法比较字符串要比使用 Equals 的速度快得多。这是因为与 IsNullOrEmpty 或者为检索 Length 属性值并将其与零比较所需执行的指令数相比,Equals 执行更多的 MSIL 指令。

您应该注意,EqualsLength == 0 对于空字符串的行为表现不同。如果您试图获取空字符串的 Length 属性的值,公共语言运行库将引发 System..::.NullReferenceException。如果比较空 (null) 字符串和空 (empty) 字符串,则公共语言运行库不会引发异常;比较将返回 false。对空字符串进行测试不会显著影响这两种方法的相对性能。当目标为 .NET Framework 2.0 时,使用 IsNullOrEmpty 方法。否则,在可能的情况下请使用 Length == 比较。

要修复与该规则的冲突,请将比较方法更改为使用 Length 属性测试空字符串。如果目标为 .NET Framework 2.0,则使用 IsNullOrEmpty 方法。

如果不用考虑性能问题,则可以安全地禁止显示此规则发出的警告。

下面的示例演示用于查找空字符串的不同技术。

namespace PerformanceLibrary
{
   public class StringTester
   {
      string s1 = "test";
 
      public void EqualsTest()
      {
         // Violates rule: TestForEmptyStringsUsingStringLength.
 
         if (s1 == "")
         {
            Console.WriteLine("s1 equals
                empty string.");
         }
      }
 
      // Use for .NET Framework 1.0 and 1.1.
      public void LengthTest()
      {
         // Satisfies rule: TestForEmptyStringsUsingStringLength.
 
         if (s1 != null && s1.Length == 0)
         {
            Console.WriteLine("s1.Length
                == 0.");
         }
      }
 
      // Use for .NET Framework 2.0.
      public void NullOrEmptyTest()
      {
         // Satisfies rule: TestForEmptyStringsUsingStringLength.
 
         if ( !String.IsNullOrEmpty(s1) )
         {
            Console.WriteLine("s1 !=
                null and s1.Length != 0.");
         }
      }
   }
}
 

Tags:

技术文章 | 代码检查

Copyright © 2009 APJ Software

最新评论

Comment RSS

公告

欢迎使用APJ Blog!

日历

<<  February 2012  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
2728291234
567891011

View posts in large calendar