CA1024 : Utiliser les propriétés lorsque cela est approprié
TypeName |
UsePropertiesWhereAppropriate |
CheckId |
CA1024 |
Catégorie |
Microsoft.CSharp |
Modification avec rupture |
Oui |
Cause
Le nom d'une méthode publique ou protégée commence par Get, n'accepte aucun paramètre et retourne une valeur qui n'est pas un tableau.
Description de la règle
Dans la plupart des cas, les propriétés représentent des données, et les méthodes exécutent des actions. Les propriétés sont accédées comme des champs, ce qui simplifie leur utilisation. Une méthode est susceptible de devenir une propriété si l'une de ces conditions est présente :
Ne prend pas d'arguments et retourne les informations d'état d'un objet.
Accepte un argument unique pour définir quelques parties de l'état d'un objet.
Les propriétés doivent se comporter comme des champs ; si la méthode ne le peut pas, elle ne doit pas être changée en propriété. Les méthodes sont meilleures que les propriétés dans les situations suivantes :
La méthode exécute une opération qui prend du temps. La méthode est perçue comme plus lente que le temps requis pour définir ou obtenir la valeur d'un champ.
La méthode exécute une conversion. L'accès à un champ ne retourne aucune version convertie des données qu'il stocke.
La méthode Get présente un effet secondaire observable. Récupérer la valeur d'un champ ne produit aucun effet secondaire.
L'ordre d'exécution est important. La définition de la valeur d'un champ ne s'appuie sur aucune autre opération qui s'est produite.
L'appel à la méthode deux fois de suite génère des résultats différents.
La méthode est statique, mais retourne un objet qui peut être modifié par l'appelant. La récupération de la valeur d'un champ ne permet pas à l'appelant de modifier les données stockées par ce champ.
La méthode retourne un tableau.
Comment corriger les violations
Pour corriger une violation de cette règle, changez la méthode en propriété.
Quand supprimer les avertissements
Supprimez un avertissement de cette règle si la méthode rencontre au moins un des critères précédemment énumérés.
Contrôle de l'expansion de propriété dans le débogueur
L'une des raisons pour lesquelles les programmeurs évitent d'utiliser une propriété est parce qu'ils ne souhaitent pas que le débogueur la développe automatiquement. Par exemple, la propriété pourrait impliquer d'allouer un grand objet ou d'appeler un P/Invoke, mais elle pourrait ne pas avoir réellement d'effets secondaires observables.
Vous pouvez empêcher le débogueur de développer automatiquement les propriétés en appliquant System.Diagnostics.DebuggerBrowsableAttribute. L'exemple suivant présente cet attribut appliqué à une propriété d'instance.
Imports System
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;
using System.Diagnostics;
namespace Microsoft.Samples
{
public class TestClass
{
// [...]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public LargeObject LargeObject
{
get
{
// Allocate large object
// [...]
}
}
}
Exemple
L'exemple suivant contient plusieurs méthodes qui doivent être converties en propriétés, et plusieurs autres qui ne le doivent pas car elles ne se comportent pas comme champs.
using System;
using System.Globalization;
using System.Collections;
namespace DesignLibrary
{
// Illustrates the behavior of rule:
// UsePropertiesWhereAppropriate.
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 will violate 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 will violate 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 will violate 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 will violate the rule, but should not be a property.
// This method performs a conversion.
public string GetWeekDayString()
{
return DateTimeFormatInfo.CurrentInfo.GetDayName(when.DayOfWeek);
}
// These methods will 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();
}
}
}