Udostępnij za pośrednictwem


CA1024: Używaj właściwości wszędzie, gdzie jest to odpowiednie

TypeName

UsePropertiesWhereAppropriate

CheckId

CA1024

Kategoria

Microsoft.Design

Zmiana kluczowa

Kluczowa

Przyczyna

Metoda publiczna lub chroniona ma nazwę, która rozpoczyna się od Get, nie przyjmuje parametrów i zwraca wartość, która nie jest tablicą.

Opis reguły

W większości przypadków właściwości reprezentują dane a metody wykonują akcje.Dostęp do właściwości jest podobny jak dostęp do pól, co ułatwia ich użycie.Metoda jest dobrym kandydatem, aby stać się właściwością, jeśli występuje jeden z poniższych warunków:

  • Nie przyjmuje żadnych argumentów i zwraca informacje o stanie obiektu.

  • Akceptuje pojedynczy argument, aby ustawić część stanu obiektu.

Właściwości powinny zachowywać się tak, jakby były polami; jeśli metoda nie jest do tego zdolna, nie powinna być zmieniana na właściwość.Metody są lepsze niż właściwości w następujących sytuacjach:

  • Metoda wykonuje czasochłonną operację.Metoda jest dostrzegalnie wolniejsza niż czas, który jest wymagany, aby ustawić lub uzyskać wartość pola.

  • Metoda wykonuje konwersję.Operacja dostępu do pola nie zwraca skonwertowanej wersji danych, które przechowuje.

  • Metoda Get posiada obserwowalny efekt uboczny.Pobieranie wartości pola nie powoduje żadnych efektów ubocznych.

  • Kolejność wykonywania jest ważna.Ustawienie wartości pola nie zależy od wystąpienia innych operacji.

  • Wywołanie metody dwa razy pod rząd tworzy różne wyniki.

  • Metoda jest statyczna, ale zwraca obiekt, który może być zmieniany przez obiekt wywołujący.Pobieranie wartości pola nie zezwala obiektowi wywołującemu na zmianę danych, które są przechowywane przez pole.

  • Metoda zwraca tablicę.

Jak naprawić naruszenia

Aby naprawić naruszenie tej reguły, należy zmienić metodę na właściwość.

Kiedy pominąć ostrzeżenia

Ostrzeżenie od tej reguły można pominąć, jeśli metoda spełnia co najmniej jedno z wcześniej wymienionych kryteriów.

Kontrolowanie rozszerzenia właściwości w debugerze

Jedną z przyczyn, dla których programiści unikają używania właściwości jest niechęć, aby debuger ją automatycznie rozszerzył.Na przykład właściwość może powodować alokację dużego obiektu lub wywoływać P/Invoke, ale może to nie powodować żadnych dostrzegalnych efektów ubocznych.

Można zapobiec automatycznemu rozwijaniu właściwości przez debuger stosując DebuggerBrowsableAttribute.Poniższy przykład pokazuje ten atrybut stosowany do właściwości wystąpienia.

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 
{ 
    public class TestClass 
    { 
        // [...] 

        [DebuggerBrowsable(DebuggerBrowsableState.Never)] 
        public LargeObject LargeObject 
        { 
            get 
            { 
                // Allocate large object 
                // [...] 

        }
    }
}

Przykład

Poniższy przykład zawiera kilka metod, które powinny zostać skonwertowane na właściwości i kilka, które nie powinny, ponieważ nie zachowują się podobnie jak pola.

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();
      }
   }
}