CA1024: Použijte vlastnosti, kde je to vhodné
Vlastnost | Hodnota |
---|---|
ID pravidla | CA1024 |
Název | Použijte vlastnosti, kde je to vhodné |
Kategorie | Návrh |
Oprava způsobující chybu nebo chybu způsobující chybu | Narušující |
Povoleno ve výchozím nastavení v .NET 9 | No |
Příčina
Metoda má název, který začíná Get
, nepřijímá žádné parametry a vrací hodnotu, která není polem.
Ve výchozím nastavení toto pravidlo sleduje pouze externě viditelné metody, ale dá se konfigurovat.
Popis pravidla
Ve většině případů vlastnosti představují data a metody provádění akcí. K vlastnostem se přistupuje jako k polím, což usnadňuje jejich použití. Metoda je vhodným kandidátem na to, aby se stala vlastností, pokud existuje jedna z těchto podmínek:
- Metoda nepřijímá žádné argumenty a vrací informace o stavu objektu.
- Metoda přijímá jeden argument pro nastavení určité části stavu objektu.
Jak opravit porušení
Chcete-li opravit porušení tohoto pravidla, změňte metodu na vlastnost.
Kdy potlačit upozornění
Pokud metoda splňuje jedno z následujících kritérií, potlačí upozornění z tohoto pravidla. V těchto situacích je vhodnější metoda než vlastnost.
- Metoda se nemůže chovat jako pole.
- Metoda provádí časově náročnou operaci. Metoda je procedučně pomalejší než doba potřebná k nastavení nebo získání hodnoty pole.
- Metoda provádí převod. Přístup k poli nevrací převedenou verzi dat, která ukládá.
- Metoda
Get
má pozorovatelný vedlejší účinek. Načtení hodnoty pole nevytváří žádné vedlejší účinky. - Pořadí provádění je důležité. Nastavení hodnoty pole nespoléhá na výskyt jiných operací.
- Volání metody dvakrát po sobě vytvoří různé výsledky.
- Metoda je
static
, ale vrací objekt, který lze změnit volajícím. Načtení hodnoty pole neumožňuje volajícímu změnit data uložená polem. - Metoda vrátí pole.
Potlačení upozornění
Pokud chcete pouze potlačit jedno porušení, přidejte do zdrojového souboru direktivy preprocesoru, abyste pravidlo zakázali a znovu povolili.
#pragma warning disable CA1024
// The code that's violating the rule is on this line.
#pragma warning restore CA1024
Pokud chcete pravidlo pro soubor, složku nebo projekt zakázat, nastavte jeho závažnost v none
konfiguračním souboru.
[*.{cs,vb}]
dotnet_diagnostic.CA1024.severity = none
Další informace naleznete v tématu Jak potlačit upozornění analýzy kódu.
Konfigurace kódu pro analýzu
Pomocí následující možnosti nakonfigurujte, ve kterých částech základu kódu se má toto pravidlo spouštět.
Tuto možnost můžete nakonfigurovat jenom pro toto pravidlo, pro všechna pravidla, která platí, nebo pro všechna pravidla v této kategorii (Návrh), na která platí. Další informace naleznete v tématu Možnosti konfigurace pravidla kvality kódu.
Zahrnutí konkrétních povrchů rozhraní API
Nastavením možnosti api_surface můžete nakonfigurovat, na kterých částech základu kódu se má toto pravidlo spouštět na základě jejich přístupnosti. Pokud chcete například určit, že pravidlo by se mělo spouštět jenom na neveřejné ploše rozhraní API, přidejte do souboru .editorconfig v projektu následující pár klíč-hodnota:
dotnet_code_quality.CAXXXX.api_surface = private, internal
Poznámka
Nahraďte XXXX
část CAXXXX
ID příslušného pravidla.
Příklad
Následující příklad obsahuje několik metod, které by měly být převedeny na vlastnosti a několik, které by neměly být, protože se chovají jako pole.
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
Rozšíření vlastnosti ovládacího prvku v ladicím programu
Jedním z důvodů, proč programátoři nepoužívají vlastnost, je, že nechtějí, aby ladicí program automaticky rozbalil. Vlastnost může například zahrnovat přidělení velkého objektu nebo volání P/Invoke, ale nemusí mít ve skutečnosti žádné pozorovatelné vedlejší účinky.
Můžete zabránit, aby ladicí program automaticky rozbalil vlastnosti použitím System.Diagnostics.DebuggerBrowsableAttribute. Následující příklad ukazuje použití tohoto atributu na vlastnost 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
// [...]
}
}
}
}