Propriétés (Guide de programmation C#)

Une propriété est un membre qui fournit un mécanisme flexible pour la lecture, l'écriture ou le calcul de la valeur d'un champ privé. Les propriétés peuvent être utilisées comme s’il s’agissait de membres de données publics, mais ce sont en fait des méthodes spéciales appelées accesseurs. Elles permettent aux données d'être facilement accessibles tout en soutenant quand même la sécurité et la flexibilité des méthodes.

Vue d’ensemble des propriétés

  • Les propriétés permettent à une classe d'exposer un moyen public d'obtenir et de définir des valeurs, tout en masquant le code d'implémentation ou de vérification.

  • Un accesseur de propriété get est utilisé pour retourner la valeur de la propriété et un accesseur de propriété set est utilisé pour affecter une nouvelle valeur. Dans C# 9 et versions ultérieures, un accesseur de propriété init est utilisé pour assigner une nouvelle valeur uniquement lors de la construction de l’objet. Ces accesseurs peuvent avoir différents niveaux d’accès. Pour plus d’informations, consultez Restriction d’accessibilité de l’accesseur.

  • Le mot clé value est utilisé pour définir la valeur assignée par l' set init accesseur ou.

  • Les propriétés peuvent être en lecture-écriture (elles ont un accesseur get et un accesseur set), en lecture seule (elles ont un accesseur get, mais pas d’accesseur set) ou en écriture seule (elles ont un accesseur set, mais pas d’accesseur get). Les propriétés en écriture seule sont rares et sont généralement utilisées pour restreindre l’accès aux données sensibles.

  • Les propriétés simples qui ne nécessitent pas de code d’accesseur personnalisé peuvent être implémentées en tant que définitions de corps d’expression ou en tant que propriétés implémentées automatiquement.

Propriétés avec des champs de stockage

Un modèle de base pour l’implémentation d’une propriété consiste à utiliser un champ de stockage privé pour définir et extraire la valeur de propriété. L’accesseur get retourne la valeur du champ privé et l’accesseur set peut effectuer une validation des données avant d’assigner une valeur au champ privé. Les deux accesseurs peuvent également effectuer des opérations de conversion ou de calcul sur les données avant de stocker ou retourner les données.

L’exemple suivant illustre ce modèle. Dans cet exemple, la classe TimePeriod représente un intervalle de temps. La classe stocke l’intervalle de temps en secondes, en interne, dans un champ privé nommé _seconds. L’utilisateur peut éventuellement spécifier l’intervalle de temps en heures à l’aide de la propriété en lecture-écriture Hours. Les deux accesseurs de propriété get et set effectuent ensuite la conversion nécessaire des heures en secondes. De plus, l’accesseur set valide les données et lève une exception ArgumentOutOfRangeException si le nombre d’heures n’est pas valide.

using System;

class TimePeriod
{
   private double _seconds;

   public double Hours
   {
       get { return _seconds / 3600; }
       set {
          if (value < 0 || value > 24)
             throw new ArgumentOutOfRangeException(
                   $"{nameof(value)} must be between 0 and 24.");

          _seconds = value * 3600;
       }
   }
}

class Program
{
   static void Main()
   {
       TimePeriod t = new TimePeriod();
       // The property assignment causes the 'set' accessor to be called.
       t.Hours = 24;

       // Retrieving the property causes the 'get' accessor to be called.
       Console.WriteLine($"Time in hours: {t.Hours}");
   }
}
// The example displays the following output:
//    Time in hours: 24

Définitions de corps d’expression

Les accesseurs de propriété sont souvent des instructions sur une ligne qui ne font qu’assigner ou retourner le résultat d’une expression. Vous pouvez implémenter ces propriétés en tant que membres expression-bodied. Les définitions de corps d’expression se composent du symbole => suivi de l’expression à assigner à la propriété ou à récupérer de la propriété.

À partir de C# 6, les propriétés en lecture seule peuvent implémenter l’accesseur get en tant que membre expression-bodied. Dans ce cas, le mot clé d’accesseur get et le mot clé return ne sont pas utilisés. L’exemple suivant implémente la propriété en lecture seule Name en tant que membre expression-bodied.

using System;

public class Person
{
   private string _firstName;
   private string _lastName;

   public Person(string first, string last)
   {
      _firstName = first;
      _lastName = last;
   }

   public string Name => $"{_firstName} {_lastName}";
}

public class Example
{
   public static void Main()
   {
      var person = new Person("Magnus", "Hedlund");
      Console.WriteLine(person.Name);
   }
}
// The example displays the following output:
//      Magnus Hedlund

À compter de C# 7.0, les accesseurs get et set peuvent être implémentés comme membres expression-bodied. Dans ce cas, les mots clés get et set doivent être spécifiés. L’exemple suivant illustre l’utilisation de définitions de corps d’expression pour les deux accesseurs. Notez que le mot clé return n’est pas utilisé avec l’accesseur get.

using System;

public class SaleItem
{
   string _name;
   decimal _cost;

   public SaleItem(string name, decimal cost)
   {
      _name = name;
      _cost = cost;
   }

   public string Name
   {
      get => _name;
      set => _name = value;
   }

   public decimal Price
   {
      get => _cost;
      set => _cost = value;
   }
}

class Program
{
   static void Main(string[] args)
   {
      var item = new SaleItem("Shoes", 19.95m);
      Console.WriteLine($"{item.Name}: sells for {item.Price:C2}");
   }
}
// The example displays output like the following:
//       Shoes: sells for $19.95

Propriétés implémentées automatiquement

Dans certains cas, les accesseurs de propriété get et set ne font qu’assigner une valeur à un champ de stockage, ou récupérer une valeur d’un champ de stockage, sans inclure de logique supplémentaire. En utilisant des propriétés implémentées automatiquement, vous simplifiez votre code, tout en laissant le compilateur C# fournir le champ de stockage de manière transparente.

Si une propriété a à la fois un get set accesseur et un (ou un get et un init ), les deux doivent être implémentés automatiquement. Vous définissez une propriété implémentée automatiquement à l’aide des mots clés get et set sans fournir d’implémentation. L’exemple suivant est identique à l’exemple précédent, sauf qu’il utilise les propriétés implémentées automatiquement Name et Price. L’exemple supprime également le constructeur paramétrable, afin que les SaleItem objets soient à présent initialisés avec un appel au constructeur sans paramètre et à un initialiseur d’objet.

using System;

public class SaleItem
{
   public string Name
   { get; set; }

   public decimal Price
   { get; set; }
}

class Program
{
   static void Main(string[] args)
   {
      var item = new SaleItem{ Name = "Shoes", Price = 19.95m };
      Console.WriteLine($"{item.Name}: sells for {item.Price:C2}");
   }
}
// The example displays output like the following:
//       Shoes: sells for $19.95

Spécification du langage C#

Pour plus d’informations, consultez Propriétés dans la spécification du langage C#. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.

Voir aussi