更新:2007 年 11 月
| TypeName | UsePropertiesWhereAppropriate | 
| CheckId | CA1024 | 
| 类别 | Microsoft.Design | 
| 是否重大更改 | 是 | 
原因
公共或受保护方法的名称以 Get 开头,没有采用任何参数或返回的值不是数组。
规则说明
在大多数情况下,属性代表数据,而方法执行操作。访问属性的方式与访问字段的方式相似,因此使用它们更容易。如果存在下列条件之一,方法就很适于成为属性:
- 不采用任何参数并返回对象的状态信息。 
- 接受单个参数来设置对象的部分状态。 
属性的表现应当与字段一样;如果该方法不是这样,则不应将其更改为属性。在下列情况下,方法比属性更适用:
- 方法执行耗时的操作。与设置或获取字段值所需的时间相比,方法的速度明显较慢。 
- 方法执行转换。访问字段不会返回它所存储的数据的转换版本。 
- Get 方法会产生明显副作用。检索字段的值不会产生任何副作用。 
- 执行的顺序很重要。设置字段的值并不依赖于已发生的其他操作。 
- 连续调用两次方法会产生不同的结果。 
- 方法是静态的,但返回了调用方可更改的对象。调用方不能通过检索某字段的值来更改该字段存储的数据。 
- 方法返回数组。 
如何修复冲突
要修复与该规则的冲突,请将方法更改为属性。
何时禁止显示警告
如果方法至少满足上文中列出的一个条件,则禁止显示与该规则有关的警告。
在调试器中控制属性扩展
程序员避免使用属性的一个原因,是他们不希望调试器自动展开属性。例如,属性可能涉及分配一个大型对象或调用 P/Invoke,但它实际上可能不具有任何明显的副作用。
通过应用 System.Diagnostics.DebuggerBrowsableAttribute 可以阻止调试器自动展开属性。下面的示例演示如何将此属性 (Attribute) 应用到实例属性 (Property)。
Imports System 
Imports System.Diagnostics 
Namespace Microsoft.Samples 
    Public Class TestClass 
        ' [...] 
        <DebuggerBrowsable(DebuggerBrowsableState.Never)> _ 
        Public ReadOnly Property LargeObject() As LargeObject 
            Get 
                ' Allocate large object 
                ' [...] 
            End Get 
        End Property 
    End Class 
End Namespace
using System; 
using System.Diagnostics; 
namespace Microsoft.Samples 
{ 
    publicclass TestClass 
    { 
        // [...] 
        [DebuggerBrowsable(DebuggerBrowsableState.Never)] 
        public LargeObject LargeObject 
        { 
            get 
            { 
                // Allocate large object 
                // [...] 
        }
    }
}
示例
下面的示例包含多个应转换为属性的方法,还包含多个由于表现与字段不同而不应转换的方法。
using System;
using System.Globalization;
using System.Collections;
namespace DesignLibrary
{
   // Illustrates the behavior of rule: 
   //  UsePropertiesWhereAppropriate.
   public class Appointment
   {
      static long nextAppointmentID;
      static double[] discountScale = {5.0, 10.0, 33.0};
      string customerName;
      long customerID;
      DateTime when;
      // Static constructor.
      static Appointment()
      {
         // Initializes the static variable for Next appointment ID.
      }
      // This method will violate the rule, but should not be a property.
      // This method has an observable side effect. 
      // Calling the method twice in succession creates different results.
      public static long GetNextAvailableID()
      {
         nextAppointmentID++;
         return nextAppointmentID - 1;
      }
      // This method will violate the rule, but should not be a property.
      // This method performs a time-consuming operation. 
      // This method returns an array.
      public Appointment[] GetCustomerHistory()
      {
         // Connect to a database to get the customer's appointment history.
         return LoadHistoryFromDB(customerID);
      }
      // This method will violate the rule, but should not be a property.
      // This method is static but returns a mutable object.
      public static double[] GetDiscountScaleForUpdate()
      {
         return discountScale;
      }
      // This method will violate the rule, but should not be a property.
      // This method performs a conversion.
      public string GetWeekDayString()
      {
         return DateTimeFormatInfo.CurrentInfo.GetDayName(when.DayOfWeek);
      }
      // These methods will violate the rule, and should be properties.
      // They each set or return a piece of the current object's state.
      public DayOfWeek GetWeekDay ()
      {
         return when.DayOfWeek;
      }
      public void  SetCustomerName (string customerName)
      {
         this.customerName = customerName;
      }
      public string GetCustomerName ()
      {
         return customerName;
      }
     public void SetCustomerID (long customerID)
      {
         this.customerID = customerID;
      }
      public long GetCustomerID ()
      {
         return customerID;
      }
      public void SetScheduleTime (DateTime when)
      {
         this.when = when;
      }
      public DateTime GetScheduleTime ()
      {
         return when;
      }
      // Time-consuming method that is called by GetCustomerHistory.
      Appointment[] LoadHistoryFromDB(long customerID)
      {
         ArrayList records = new ArrayList();
         // Load from database.
         return (Appointment[])records.ToArray();
      }
   }
}