CA1024: Use propriedades onde apropriado

Propriedade valor
ID da regra CA1024
Cargo Use propriedades quando apropriado
Categoria Desenho
A correção está quebrando ou não quebrando Quebrando
Habilitado por padrão no .NET 8 Não

Causa

Um método tem um nome que começa com Get, não usa parâmetros e retorna um valor que não é uma matriz.

Por padrão, essa regra examina apenas métodos visíveis externamente, mas isso é configurável.

Descrição da regra

Na maioria dos casos, as propriedades representam dados e os métodos executam ações. As propriedades são acessadas como campos, o que as torna mais fáceis de usar. Um método é um bom candidato para se tornar uma propriedade se uma destas condições estiver presente:

  • O método não usa argumentos e retorna as informações de estado de um objeto.
  • O método aceita um único argumento para definir alguma parte do estado de um objeto.

Como corrigir violações

Para corrigir uma violação dessa regra, altere o método para uma propriedade.

Quando suprimir avisos

Suprima um aviso dessa regra se o método atender a um dos seguintes critérios. Nestas situações, um método é preferível a uma propriedade.

  • O método não pode se comportar como um campo.
  • O método executa uma operação demorada. O método é visivelmente mais lento do que o tempo necessário para definir ou obter o valor de um campo.
  • O método executa uma conversão. O acesso a um campo não retorna uma versão convertida dos dados que ele armazena.
  • O Get método tem um efeito colateral observável. Recuperar o valor de um campo não produz quaisquer efeitos secundários.
  • A ordem de execução é importante. A definição do valor de um campo não depende da ocorrência de outras operações.
  • Chamar o método duas vezes consecutivas cria resultados diferentes.
  • O método é static mas retorna um objeto que pode ser alterado pelo chamador. Recuperar o valor de um campo não permite que o chamador altere os dados armazenados pelo campo.
  • O método retorna uma matriz.

Suprimir um aviso

Se você quiser apenas suprimir uma única violação, adicione diretivas de pré-processador ao seu arquivo de origem para desativar e, em seguida, reativar a regra.

#pragma warning disable CA1024
// The code that's violating the rule is on this line.
#pragma warning restore CA1024

Para desabilitar a regra de um arquivo, pasta ou projeto, defina sua gravidade como none no arquivo de configuração.

[*.{cs,vb}]
dotnet_diagnostic.CA1024.severity = none

Para obter mais informações, consulte Como suprimir avisos de análise de código.

Configurar código para análise

Use a opção a seguir para configurar em quais partes da sua base de código executar essa regra.

Você pode configurar essa opção apenas para esta regra, para todas as regras às quais ela se aplica ou para todas as regras nesta categoria (Design) às quais ela se aplica. Para obter mais informações, consulte Opções de configuração da regra de qualidade de código.

Incluir superfícies de API específicas

Você pode configurar em quais partes da sua base de código executar essa regra, com base em sua acessibilidade. Por exemplo, para especificar que a regra deve ser executada somente na superfície de API não pública, adicione o seguinte par chave-valor a um arquivo .editorconfig em seu projeto:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Exemplo

O exemplo a seguir contém vários métodos que devem ser convertidos em propriedades e vários que não devem porque não se comportam como campos.

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 violates 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 violates 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 violates 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 violates the rule, but should not be a property.
    // This method performs a conversion.
    public string GetWeekDayString()
    {
        return DateTimeFormatInfo.CurrentInfo.GetDayName(when.DayOfWeek);
    }

    // These methods 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();
    }
}
Public Class Appointment
    Shared nextAppointmentID As Long
    Shared discountScale As Double() = {5.0, 10.0, 33.0}
    Private customerName As String
    Private customerID As Long
    Private [when] As Date

    ' Static constructor.
    Shared Sub New()
        ' Initializes the static variable for Next appointment ID.
    End Sub

    ' This method violates 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 Shared Function GetNextAvailableID() As Long
        nextAppointmentID += 1
        Return nextAppointmentID - 1
    End Function

    ' This method violates the rule, but should not be a property.
    ' This method performs a time-consuming operation. 
    ' This method returns an array.
    Public Function GetCustomerHistory() As Appointment()
        ' Connect to a database to get the customer's appointment history.
        Return LoadHistoryFromDB(customerID)
    End Function

    ' This method violates the rule, but should not be a property.
    ' This method is static but returns a mutable object.
    Public Shared Function GetDiscountScaleForUpdate() As Double()
        Return discountScale
    End Function

    ' This method violates the rule, but should not be a property.
    ' This method performs a conversion.
    Public Function GetWeekDayString() As String
        Return DateTimeFormatInfo.CurrentInfo.GetDayName([when].DayOfWeek)
    End Function

    ' These methods violate the rule and should be properties.
    ' They each set or return a piece of the current object's state.

    Public Function GetWeekDay() As DayOfWeek
        Return [when].DayOfWeek
    End Function

    Public Sub SetCustomerName(customerName As String)
        Me.customerName = customerName
    End Sub

    Public Function GetCustomerName() As String
        Return customerName
    End Function

    Public Sub SetCustomerID(customerID As Long)
        Me.customerID = customerID
    End Sub

    Public Function GetCustomerID() As Long
        Return customerID
    End Function

    Public Sub SetScheduleTime([when] As Date)
        Me.[when] = [when]
    End Sub

    Public Function GetScheduleTime() As Date
        Return [when]
    End Function

    ' Time-consuming method that is called by GetCustomerHistory.
    Private Function LoadHistoryFromDB(customerID As Long) As Appointment()
        Dim records As ArrayList = New ArrayList()
        Return CType(records.ToArray(), Appointment())
    End Function
End Class

Controlar a expansão da propriedade no depurador

Uma razão pela qual os programadores evitam usar uma propriedade é porque eles não querem que o depurador a expanda automaticamente. Por exemplo, a propriedade pode envolver a alocação de um objeto grande ou chamar um P/Invoke, mas pode não ter efeitos colaterais observáveis.

Você pode impedir que o depurador expanda automaticamente as propriedades aplicando System.Diagnostics.DebuggerBrowsableAttribute. O exemplo a seguir mostra esse atributo sendo aplicado a uma propriedade de instância.

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.Diagnostics;

namespace Microsoft.Samples
{
    class TestClass
    {
        // [...]

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