CA1024: Nach Möglichkeit Eigenschaften verwenden.
Eigenschaft | Wert |
---|---|
Regel-ID | CA1024 |
Titel | Nach Möglichkeit Eigenschaften verwenden. |
Kategorie | Design |
Fix führt oder führt nicht zur Unterbrechung | Breaking |
Standardmäßig in .NET 9 aktiviert | No |
Ursache
Eine Methode weist einen Namen auf, der mit Get
beginnt. Sie nimmt keine Parameter an und gibt einen Wert zurück, bei dem es sich nicht um ein Array handelt.
Standardmäßig werden mit dieser Regel nur extern sichtbare Methoden überprüft, aber dies ist konfigurierbar.
Regelbeschreibung
In den meisten Fällen stellen Eigenschaften Daten dar, und Methoden führen Aktionen aus. Der Zugriff auf Eigenschaften erfolgt wie bei Feldern, sodass sie einfacher zu verwenden sind. Eine Methode ist ein guter Kandidat für eine Eigenschaft, wenn eine der folgenden Bedingungen erfüllt wird:
- Die Methode nimmt keine Argumente an und gibt die Zustandsinformationen eines Objekts zurück.
- Die Methode akzeptiert ein einzelnes Argument, um einen Teil des Zustands eines Objekts festzulegen.
Behandeln von Verstößen
Um einen Verstoß gegen diese Regel zu beheben, ändern Sie die Methode in eine Eigenschaft.
Wann sollten Warnungen unterdrückt werden?
Unterdrücken Sie eine Warnung von dieser Regel, wenn die Methode eines der folgenden Kriterien erfüllt. In diesen Fällen ist eine Methode einer Eigenschaft vorzuziehen.
- Die Methode kann sich nicht als Feld verhalten.
- Die Methode führt einen zeitaufwändigen Vorgang aus. Die-Methode ist merklich langsamer als die Zeit, die zum Festlegen oder Abrufen des Werts eines Felds erforderlich ist.
- Die Methode führt eine Konvertierung aus. Beim Zugriff auf ein Feld wird keine konvertierte Version der darin gespeicherten Daten zurückgegeben.
- Die
Get
-Methode führt zu wahrnehmbaren Nebenwirkungen. Beim Abrufen des Werts eines Felds treten keine Nebenwirkungen auf. - Die Reihenfolge der Ausführung ist von Bedeutung. Der Wert eines Felds wird nicht basierend auf dem Vorkommen anderer Vorgänge festgelegt.
- Der zweimalige Aufruf der Methode in Folge führt zu unterschiedlichen Ergebnissen.
- Die-Methode ist
static
, gibt jedoch ein Objekt zurück, das vom Aufrufer geändert werden kann. Wenn der Aufrufer den Wert eines Felds abruft, kann er die vom Feld gespeicherten Daten nicht ändern. - Die Methode gibt ein Array zurück.
Unterdrücken einer Warnung
Um nur eine einzelne Verletzung zu unterdrücken, fügen Sie der Quelldatei Präprozessoranweisungen hinzu, um die Regel zu deaktivieren und dann wieder zu aktivieren.
#pragma warning disable CA1024
// The code that's violating the rule is on this line.
#pragma warning restore CA1024
Um die Regel für eine Datei, einen Ordner oder ein Projekt zu deaktivieren, legen Sie den Schweregrad in der Konfigurationsdatei auf none
fest.
[*.{cs,vb}]
dotnet_diagnostic.CA1024.severity = none
Weitere Informationen finden Sie unter Vorgehensweise: Unterdrücken von Codeanalyse-Warnungen.
Konfigurieren des zu analysierenden Codes
Mithilfe der folgenden Option können Sie konfigurieren, für welche Teile Ihrer Codebasis diese Regel ausgeführt werden soll.
Sie können diese Optionen nur für diese Regel, für alle zutreffenden Regeln oder für alle zutreffenden Regeln in dieser Kategorie (Entwurf) konfigurieren. Weitere Informationen finden Sie unter Konfigurationsoptionen für die Codequalitätsregel.
Einschließen bestimmter API-Oberflächen
Sie können je nach Zugänglichkeit festlegen, für welche Bestandteile Ihrer Codebasis diese Regel ausgeführt wird. Sie können beispielsweise festlegen, dass die Regel nur für die nicht öffentliche API-Oberfläche ausgeführt werden soll, indem Sie einer EDITORCONFIG-Datei in Ihrem Projekt das folgende Schlüssel-Wert-Paar hinzufügen:
dotnet_code_quality.CAXXXX.api_surface = private, internal
Beispiel
Das folgende Beispiel enthält mehrere Methoden, die in Eigenschaften konvertiert werden sollten, sowie mehrere Methoden, die nicht konvertiert werden sollten, weil sie sich nicht wie Felder verhalten.
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
Steuern der Eigenschaftserweiterung im Debugger
Ein Grund dafür, warum Programmierer die Verwendung einer Eigenschaft vermeiden, liegt darin, dass sie vom Debugger nicht automatisch erweitert werden soll. Die Eigenschaft kann z. B. das Zuordnen eines großen Objekts oder das Aufrufen von P/Invoke beinhalten, aber es treten möglicherweise tatsächlich keine merklichen Nebenwirkungen auf.
Sie können die automatische Erweiterung von Eigenschaften durch den Debugger verhindern, indem Sie System.Diagnostics.DebuggerBrowsableAttribute anwenden. Das folgende Beispiel zeigt, wie dieses Attribut auf eine Instanzeigenschaft angewendet wird.
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
// [...]
}
}
}
}