CA1024: Używaj właściwości wszędzie, gdzie jest to odpowiednie
Właściwości | Wartość |
---|---|
Identyfikator reguły | CA1024 |
Tytuł | Używaj właściwości, o ile to możliwe |
Kategoria | Projekt |
Poprawka powodująca niezgodność lub niezgodność | Kluczowa |
Domyślnie włączone na platformie .NET 9 | Nie. |
Przyczyna
Metoda ma nazwę rozpoczynającą się od Get
, nie przyjmuje parametrów i zwraca wartość, która nie jest tablicą.
Domyślnie ta reguła analizuje tylko metody widoczne zewnętrznie, ale jest to możliwe do skonfigurowania.
Opis reguły
W większości przypadków właściwości reprezentują dane i metody wykonywania akcji. Dostęp do właściwości można uzyskać, takich jak pola, co ułatwia ich używanie. Metoda jest dobrym kandydatem, aby stać się właściwością, jeśli jeden z tych warunków jest obecny:
- Metoda nie przyjmuje żadnych argumentów i zwraca informacje o stanie obiektu.
- Metoda akceptuje pojedynczy argument, aby ustawić część stanu obiektu.
Jak naprawić naruszenia
Aby naprawić naruszenie tej reguły, zmień metodę na właściwość.
Kiedy pomijać ostrzeżenia
Pomiń ostrzeżenie z tej reguły, jeśli metoda spełnia jedno z następujących kryteriów. W takich sytuacjach metoda jest preferowana dla właściwości.
- Metoda nie może zachowywać się jako pole.
- Metoda wykonuje czasochłonną operację. Metoda jest prawdopodobnie wolniejsza niż czas wymagany do ustawienia lub pobrania wartości pola.
- Metoda wykonuje konwersję. Uzyskiwanie dostępu do pola nie zwraca przekonwertowanej wersji przechowywanych danych.
- Metoda
Get
ma zauważalny efekt uboczny. Pobieranie wartości pola nie powoduje żadnych skutków ubocznych. - Kolejność wykonywania jest ważna. Ustawienie wartości pola nie polega na wystąpieniu innych operacji.
- Wywołanie metody dwa razy z rzędu powoduje utworzenie różnych wyników.
- Metoda jest
static
ale zwraca obiekt, który można zmienić przez obiekt wywołujący. Pobieranie wartości pola nie zezwala wywołującym na zmianę danych przechowywanych przez pole. - Metoda zwraca tablicę.
Pomijanie ostrzeżenia
Jeśli chcesz po prostu pominąć pojedyncze naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć regułę.
#pragma warning disable CA1024
// The code that's violating the rule is on this line.
#pragma warning restore CA1024
Aby wyłączyć regułę dla pliku, folderu lub projektu, ustaw jego ważność na none
w pliku konfiguracji.
[*.{cs,vb}]
dotnet_diagnostic.CA1024.severity = none
Aby uzyskać więcej informacji, zobacz Jak pominąć ostrzeżenia dotyczące analizy kodu.
Konfigurowanie kodu do analizowania
Użyj następującej opcji, aby skonfigurować, które części bazy kodu mają być uruchamiane w tej regule.
Tę opcję można skonfigurować tylko dla tej reguły, dla wszystkich reguł, do których ma ona zastosowanie, lub dla wszystkich reguł w tej kategorii (Projekt), których dotyczy. Aby uzyskać więcej informacji, zobacz Opcje konfiguracji reguły jakości kodu.
Uwzględnij określone powierzchnie interfejsu API
Możesz skonfigurować, na których częściach bazy kodu ma być uruchamiana ta reguła, na podstawie ich ułatwień dostępu. Aby na przykład określić, że reguła powinna być uruchamiana tylko na powierzchni niepublicznego interfejsu API, dodaj następującą parę klucz-wartość do pliku editorconfig w projekcie:
dotnet_code_quality.CAXXXX.api_surface = private, internal
Przykład
Poniższy przykład zawiera kilka metod, które powinny być konwertowane na właściwości i kilka, które nie powinny zachowywać się jak pola.
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
Rozszerzanie właściwości kontrolki w debugerze
Jednym z powodów, dla których programiści unikają używania właściwości, jest to, że nie chcą, aby debuger automatycznie go rozpalił. Na przykład właściwość może obejmować przydzielanie dużego obiektu lub wywoływanie wywołania P/Invoke, ale może nie mieć żadnych zauważalnych skutków ubocznych.
Aby zapobiec automatycznemu rozszerzaniu właściwości debugera, zastosuj polecenie System.Diagnostics.DebuggerBrowsableAttribute. W poniższym przykładzie pokazano, że ten atrybut jest stosowany do właściwości wystąpienia.
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
// [...]
}
}
}
}