다음을 통해 공유


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

속성
규칙 ID CA1024
타이틀 적합한 속성을 사용하세요.
범주 디자인
수정 사항이 주요 변경인지 여부 주요 변경
.NET 8에서 기본적으로 사용 아니요

원인

메서드가 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 표면에서만 실행되도록 지정하려면 프로젝트의 .editorconfig 파일에 다음 키-값 쌍을 추가합니다.

dotnet_code_quality.CAXXXX.api_surface = private, internal

예시

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

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

디버거의 컨트롤 속성 확장

프로그래머가 속성을 사용하지 않는 한 가지 이유는 디버거가 이를 자동 확장하는 것을 원하지 않기 때문입니다. 예를 들어 속성에 큰 개체를 할당하거나 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
                // [...]
            }
        }
    }
}