언어

CA1024: 적합한 속성을 사용하십시오.

속성 값
규칙 ID CA1024
제목 적합한 속성을 사용하세요.
범주 디자인
수정 사항이 호환성을 깨뜨리는지 여부 또는 무중단인지 여부 주요 변경
.NET 10에서 기본적으로 사용하도록 설정 아니요
적용 가능한 언어 C# 및 Visual Basic

원인

메서드가 Get으로 시작하는 이름을 사용하고, 매개 변수를 사용하지 않으며, 배열이 아닌 값을 반환합니다.

기본적으로 이 규칙은 외부에 표시되는 메서드만 확인하지만 이는 구성 가능합니다.

규칙 설명

대부분의 경우 속성은 데이터를 나타내고 메서드는 작업을 수행합니다. 속성은 필드처럼 액세스되므로 더 쉽게 사용할 수 있습니다. 다음과 같은 조건 중 하나가 있는 메서드는 속성이 될 수 있는 좋은 후보입니다.

  • 메서드가 인수를 사용하지 않고 개체의 상태 정보를 반환합니다.
  • 메서드가 단일 인수를 수락하여 개체 상태의 일부를 설정합니다.

위반 문제를 해결하는 방법

이 규칙의 위반 문제를 해결하려면 메서드를 속성으로 변경합니다.

경고를 표시하지 않는 경우

메서드가 다음 조건 중 하나를 충족하는 경우 이 규칙에서 경고를 표시하지 않습니다. 이러한 상황에서는 속성보다 메서드가 선호됩니다.

  • 메서드가 필드로 동작할 수 없습니다.
  • 메서드가 시간이 많이 걸리는 작업을 수행합니다. 메서드는 필드 값을 설정하거나 가져오는 데 필요한 시간보다 확실히 느립니다.
  • 메서드가 변환을 수행합니다. 필드는 액세스하면 저장된 데이터의 변환된 버전을 반환하지 않습니다.
  • Get 메서드에 관찰 가능한 부작용이 있습니다. 필드의 값을 검색해도 부작용이 발생하지 않습니다.
  • 실행 순서가 중요합니다. 필드의 값을 설정해도 다른 작업의 발생에 의존하지 않습니다.
  • 메서드를 연속해서 두 번 호출하면 다른 결과가 생성됩니다.
  • 메서드는 static이지만 호출자가 변경할 수 있는 개체를 반환합니다. 필드의 값을 검색해도 호출자가 필드에 저장된 데이터를 변경할 수 없습니다.
  • 메서드가 배열을 반환합니다.

경고 표시 안 함

단일 위반을 억제하려면 원본 파일에 전처리기 지시문을 추가하여 규칙을 비활성화한 후 다시 활성화하십시오.

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

파일, 폴더 또는 프로젝트에 대한 규칙을 사용하지 않으려면 구성 파일에서 none의 심각도를 설정합니다.

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

자세한 내용은 방법: 코드 분석 경고 표시 안 함을 참조하세요.

분석할 코드 구성

다음 옵션을 사용하여 이 규칙이 실행될 코드베이스 부분을 구성합니다.

이 규칙, 적용되는 모든 규칙 또는 적용되는 이 범주(디자인)의 모든 규칙에 대해 이 옵션을 구성할 수 있습니다. 자세한 내용은 코드 품질 규칙 구성 옵션을 참조하세요.

특정 API 화면 포함

api_surface 옵션을 설정하여 접근성에 따라 이 규칙을 실행할 코드베이스의 일부를 구성할 수 있습니다. 예를 들어 규칙이 퍼블릭이 아닌 API 표면에서만 실행되도록 지정하려면 프로젝트의 .editorconfig 파일에 다음 키-값 쌍을 추가합니다.

dotnet_code_quality.CAXXXX.api_surface = private, internal

메모

XXXX CAXXXX 부분을 해당 규칙의 ID로 바꿉니다.

예시

다음 예제에는 속성으로 변환되어야 하는 몇 가지 메서드와 필드처럼 동작하지 않아야 하는 여러 메서드가 포함되어 있습니다.

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 = [];
        // 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

디버거의 컨트롤 속성 확장

프로그래머가 속성을 사용하지 않는 한 가지 이유는 디버거가 이를 자동 확장하는 것을 원하지 않기 때문입니다. 예를 들어 속성에 큰 개체를 할당하거나 P/Invoke를 호출하는 동작이 포함될 수 있지만 실제로는 관찰 가능한 부작용이 없을 수 있습니다.

System.Diagnostics.DebuggerBrowsableAttribute를 적용하여 디버거가 속성을 자동 확장하는 것을 방지할 수 있습니다. 다음 예제에서는 이 특성을 instance 속성에 적용하는 방법을 보여 줍니다.

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
                // [...]
            }
        }
    }
}