Utilisation de propriétés (Guide de programmation C#)Using Properties (C# Programming Guide)

Les propriétés allient des caractéristiques des champs et des méthodes.Properties combine aspects of both fields and methods. Pour l’utilisateur d’un objet, une propriété s’apparente à un champ. Pour accéder à celle-ci, il doit utiliser la même syntaxe.To the user of an object, a property appears to be a field, accessing the property requires the same syntax. Pour l’implémenteur d’une classe, une propriété est constituée d’un ou deux blocs de code, représentant un accesseur get et/ou un accesseur set.To the implementer of a class, a property is one or two code blocks, representing a get accessor and/or a set accessor. Le bloc de code correspondant à l’accesseur get est exécuté à la lecture de la propriété ; le bloc de code correspondant à l’accesseur set est exécuté au moment où une nouvelle valeur est assignée à la propriété.The code block for the get accessor is executed when the property is read; the code block for the set accessor is executed when the property is assigned a new value. Une propriété sans accesseur set est considérée comme étant en lecture seule.A property without a set accessor is considered read-only. Une propriété sans accesseur get est considérée comme étant en écriture seule.A property without a get accessor is considered write-only. Une propriété qui possède les deux accesseurs est en lecture-écriture.A property that has both accessors is read-write.

Contrairement aux champs, les propriétés ne sont pas classifiées en tant que variables.Unlike fields, properties are not classified as variables. Par conséquent, vous ne pouvez pas passer une propriété en tant que paramètre ref ou out.Therefore, you cannot pass a property as a ref or out parameter.

Les propriétés ont diverses utilisations : elles peuvent valider les données avant d’autoriser une modification ; elles peuvent exposer de manière transparente les données d’une classe quand celles-ci sont effectivement extraites d’une autre source, telle qu’une base de données ; elles peuvent effectuer une action quand des données sont modifiées, comme déclencher un événement ou modifier la valeur d’autres champs.Properties have many uses: they can validate data before allowing a change; they can transparently expose data on a class where that data is actually retrieved from some other source, such as a database; they can take an action when data is changed, such as raising an event, or changing the value of other fields.

Les propriétés sont déclarées dans le bloc de classe en spécifiant le niveau d’accès du champ, suivi du type de la propriété, du nom de la propriété et d’un bloc de code qui déclare un accesseur get et/ou un accesseur set.Properties are declared in the class block by specifying the access level of the field, followed by the type of the property, followed by the name of the property, and followed by a code block that declares a get-accessor and/or a set accessor. Exemple :For example:

public class Date
{
    private int month = 7;  // Backing store

    public int Month
    {
        get
        {
            return month;
        }
        set
        {
            if ((value > 0) && (value < 13))
            {
                month = value;
            }
        }
    }
}

Dans cet exemple, Month est déclaré en tant que propriété pour permettre à l’accesseur set de vérifier que la valeur définie de Month se trouve bien entre 1 et 12.In this example, Month is declared as a property so that the set accessor can make sure that the Month value is set between 1 and 12. La propriété Month utilise un champ privé pour assurer le suivi de la valeur réelle.The Month property uses a private field to track the actual value. L’emplacement réel des données d’une propriété est souvent appelé « magasin de stockage » de la propriété.The real location of a property's data is often referred to as the property's "backing store." Il est courant que les propriétés utilisent des champs privés comme magasin de stockage.It is common for properties to use private fields as a backing store. Le champ est marqué comme étant privé pour garantir qu’il ne peut être modifié qu’en appelant la propriété.The field is marked private in order to make sure that it can only be changed by calling the property. Pour plus d’informations sur les restrictions d’accès public et privé, consultez Modificateurs d’accès.For more information about public and private access restrictions, see Access Modifiers.

Les propriétés implémentées automatiquement fournissent une syntaxe simplifiée pour des déclarations de propriété simples.Auto-implemented properties provide simplified syntax for simple property declarations. Pour plus d’informations, consultez Propriétés implémentées automatiquement.For more information, see Auto-Implemented Properties.

Accesseur getThe get Accessor

Le corps de l’accesseur get ressemble à celui d’une méthode.The body of the get accessor resembles that of a method. Il doit retourner une valeur du type de la propriété.It must return a value of the property type. L’exécution de l’accesseur get revient à lire la valeur du champ.The execution of the get accessor is equivalent to reading the value of the field. Par exemple, quand vous retournez la variable privée de l’accesseur get et que les optimisations sont activées, l’appel à la méthode de l’accesseur get est intégré (inline) par le compilateur, si bien il n’existe aucune surcharge d’appel de méthode.For example, when you are returning the private variable from the get accessor and optimizations are enabled, the call to the get accessor method is inlined by the compiler so there is no method-call overhead. Cependant, une méthode d’accesseur get virtuelle ne peut pas être inline, car le compilateur ne sait pas au moment de la compilation quelle méthode peut être effectivement appelée au moment de l’exécution.However, a virtual get accessor method cannot be inlined because the compiler does not know at compile-time which method may actually be called at run time. Voici un exemple d’accesseur get qui retourne la valeur d’un champ privé name :The following is a get accessor that returns the value of a private field name:

class Person
{
    private string name;  // the name field
    public string Name    // the Name property
    {
        get
        {
            return name;
        }
    }
}

Quand vous faites référence à la propriété (pas en tant que cible d’une assignation), l’accesseur get est appelé pour lire la valeur de la propriété.When you reference the property, except as the target of an assignment, the get accessor is invoked to read the value of the property. Exemple :For example:

Person person = new Person();
//...

System.Console.Write(person.Name);  // the get accessor is invoked here

L’accesseur get doit se terminer dans une instruction return ou throw et le contrôle ne peut pas déborder du corps de l’accesseur.The get accessor must end in a return or throw statement, and control cannot flow off the accessor body.

Modifier l’état de l’objet en utilisant l’accesseur get n’est pas un style de programmation approprié.It is a bad programming style to change the state of the object by using the get accessor. Par exemple, l’accesseur suivant s’accompagne d’un effet secondaire, à savoir que l’état de l’objet est modifié chaque fois que le champ number fait l’objet d’un accès.For example, the following accessor produces the side effect of changing the state of the object every time that the number field is accessed.

private int number;
public int Number
{
    get
    {
        return number++;   // Don't do this
    }
}

L’accesseur get peut être utilisé pour retourner la valeur du champ ou pour la calculer et la retourner.The get accessor can be used to return the field value or to compute it and return it. Exemple :For example:

class Employee
{
    private string name;
    public string Name
    {
        get
        {
            return name != null ? name : "NA";
        }
    }
}

Dans le segment de code précédent, si vous n’assignez pas de valeur à la propriété Name, elle retourne la valeur NA.In the previous code segment, if you do not assign a value to the Name property, it will return the value NA.

Accesseur SetThe set Accessor

L’accesseur set ressemble à une méthode dont le type de retour est void.The set accessor resembles a method whose return type is void. Il utilise un paramètre implicite nommé value, dont le type est celui de la propriété.It uses an implicit parameter called value, whose type is the type of the property. Dans l’exemple ci-dessous, un accesseur set est ajouté à la propriété Name :In the following example, a set accessor is added to the Name property:

class Person
{
    private string name;  // the name field
    public string Name    // the Name property
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
        }
    }
}

Quand vous assignez une valeur à la propriété, l’accesseur set est appelé en utilisant un argument qui fournit la nouvelle valeur.When you assign a value to the property, the set accessor is invoked by using an argument that provides the new value. Exemple :For example:

Person person = new Person();
person.Name = "Joe";  // the set accessor is invoked here                

System.Console.Write(person.Name);  // the get accessor is invoked here

Il s’agit d’une erreur d’utiliser le nom de paramètre implicite, value, pour une déclaration de variable locale dans un accesseur set.It is an error to use the implicit parameter name, value, for a local variable declaration in a set accessor.

NotesRemarks

Les propriétés peuvent être marquées comme étant public, private, protected, internal, protected internal ou private protected.Properties can be marked as public, private, protected, internal, protected internal or private protected. Ces modificateurs d’accès définissent comment les utilisateurs de la classe peuvent accéder à la propriété.These access modifiers define how users of the class can access the property. Les accesseurs get et set d’une même propriété peuvent avoir des modificateurs d’accès différents.The get and set accessors for the same property may have different access modifiers. Par exemple, l’accesseur get peut être public pour autoriser l’accès en lecture seule en dehors du type, tandis que l’accesseur set peut être private ou protected.For example, the get may be public to allow read-only access from outside the type, and the set may be private or protected. Pour plus d’informations, consultez la page Modificateurs d’accès.For more information, see Access Modifiers.

Une propriété peut être déclarée en tant que propriété statique à l’aide du mot clé static.A property may be declared as a static property by using the static keyword. La propriété devient ainsi accessible à tout moment aux appelants, même s’il n’existe aucune instance de la classe.This makes the property available to callers at any time, even if no instance of the class exists. Pour plus d’informations, consultez Classes statiques et membres de classe statique.For more information, see Static Classes and Static Class Members.

Une propriété peut être marquée comme étant une propriété virtuelle à l’aide du mot clé virtual.A property may be marked as a virtual property by using the virtual keyword. Cela permet aux classes dérivées de substituer le comportement de la propriété à l’aide du mot clé override.This enables derived classes to override the property behavior by using the override keyword. Pour plus d'informations sur ces options, consultez Héritage.For more information about these options, see Inheritance.

Un propriété qui se substitue à une propriété virtuelle peut aussi être sealed, ce qui signifie que pour les classes dérivées, elle n’est plus virtuelle.A property overriding a virtual property can also be sealed, specifying that for derived classes it is no longer virtual. Enfin, une propriété peut être déclarée comme étant abstract.Lastly, a property can be declared abstract. Cela signifie qu’il n’existe aucune implémentation dans la classe et que les classes dérivées doivent écrire leur propre implémentation.This means that there is no implementation in the class, and derived classes must write their own implementation. Pour plus d’informations sur ces options, consultez Classes abstract et sealed et membres de classe.For more information about these options, see Abstract and Sealed Classes and Class Members.

Note

Il s’agit d’une erreur d’utiliser un modificateur virtual, abstract ou override sur un accesseur de propriété static.It is an error to use a virtual, abstract, or override modifier on an accessor of a static property.

ExempleExample

Cet exemple illustre les propriétés d’instance, statiques et en lecture seule.This example demonstrates instance, static, and read-only properties. Il accepte le nom de l’employé à partir du clavier, incrémente NumberOfEmployees de 1 et affiche le nom et le numéro de l’employé.It accepts the name of the employee from the keyboard, increments NumberOfEmployees by 1, and displays the Employee name and number.

public class Employee
{
    public static int NumberOfEmployees;
    private static int counter;
    private string name;

    // A read-write instance property:
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    // A read-only static property:
    public static int Counter
    {
        get { return counter; }
    }

    // A Constructor:
    public Employee()
    {
        // Calculate the employee's number:
        counter = ++NumberOfEmployees;
    }
}

class TestEmployee
{
    static void Main()
    {
        Employee.NumberOfEmployees = 107;
        Employee e1 = new Employee();
        e1.Name = "Claude Vige";

        System.Console.WriteLine("Employee number: {0}", Employee.Counter);
        System.Console.WriteLine("Employee name: {0}", e1.Name);
    }
}
/* Output:
    Employee number: 108
    Employee name: Claude Vige
*/

ExempleExample

Cet exemple montre comment accéder à une propriété de classe de base qui est masquée par une autre propriété qui porte le même nom dans une classe dérivée.This example demonstrates how to access a property in a base class that is hidden by another property that has the same name in a derived class.

public class Employee
{
    private string name;
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}

public class Manager : Employee
{
    private string name;

    // Notice the use of the new modifier:
    public new string Name
    {
        get { return name; }
        set { name = value + ", Manager"; }
    }
}

class TestHiding
{
    static void Main()
    {
        Manager m1 = new Manager();

        // Derived class property.
        m1.Name = "John";

        // Base class property.
        ((Employee)m1).Name = "Mary";

        System.Console.WriteLine("Name in the derived class is: {0}", m1.Name);
        System.Console.WriteLine("Name in the base class is: {0}", ((Employee)m1).Name);
    }
}
/* Output:
    Name in the derived class is: John, Manager
    Name in the base class is: Mary
*/

Voici les points importants de l’exemple précédent :The following are important points in the previous example:

  • La propriété Name de la classe dérivée masque la propriété Name de la classe de base.The property Name in the derived class hides the property Name in the base class. En pareil cas, le modificateur new est utilisé dans la déclaration de la propriété de la classe dérivée :In such a case, the new modifier is used in the declaration of the property in the derived class:

    public new string Name
    
  • La conversion de type (Employee) est utilisée pour accéder à la propriété masquée de la classe de base :The cast (Employee) is used to access the hidden property in the base class:

    ((Employee)m1).Name = "Mary";
    

    Pour plus d’informations sur le masquage des membres, consultez new, modificateur.For more information about hiding members, see the new Modifier.

ExempleExample

Dans cet exemple, deux classes, Cube et Square, implémentent une classe abstract, Shape, et remplacent sa propriété Area abstract.In this example, two classes, Cube and Square, implement an abstract class, Shape, and override its abstract Area property. Notez l’utilisation du modificateur override sur les propriétés.Note the use of the override modifier on the properties. Le programme accepte le côté (« side ») comme entrée et calcule les surfaces (« areas ») du carré (« square ») et du cube.The program accepts the side as an input and calculates the areas for the square and cube. De même, il accepte la surface (« area ») comme entrée et calcule le côté (« side ») correspondant du carré (« square ») et du cube.It also accepts the area as an input and calculates the corresponding side for the square and cube.

abstract class Shape
{
    public abstract double Area
    {
        get;
        set;
    }
}

class Square : Shape
{
    public double side;

    public Square(double s)  //constructor
    {
        side = s;
    }

    public override double Area
    {
        get
        {
            return side * side;
        }
        set
        {
            side = System.Math.Sqrt(value);
        }
    }
}

class Cube : Shape
{
    public double side;

    public Cube(double s)
    {
        side = s;
    }

    public override double Area
    {
        get
        {
            return 6 * side * side;
        }
        set
        {
            side = System.Math.Sqrt(value / 6);
        }
    }
}

class TestShapes
{
    static void Main()
    {
        // Input the side:
        System.Console.Write("Enter the side: ");
        double side = double.Parse(System.Console.ReadLine());

        // Compute the areas:
        Square s = new Square(side);
        Cube c = new Cube(side);

        // Display the results:
        System.Console.WriteLine("Area of the square = {0:F2}", s.Area);
        System.Console.WriteLine("Area of the cube = {0:F2}", c.Area);
        System.Console.WriteLine();

        // Input the area:
        System.Console.Write("Enter the area: ");
        double area = double.Parse(System.Console.ReadLine());

        // Compute the sides:
        s.Area = area;
        c.Area = area;

        // Display the results:
        System.Console.WriteLine("Side of the square = {0:F2}", s.side);
        System.Console.WriteLine("Side of the cube = {0:F2}", c.side);
    }
}
/* Example Output:
    Enter the side: 4
    Area of the square = 16.00
    Area of the cube = 96.00

    Enter the area: 24
    Side of the square = 4.90
    Side of the cube = 2.00
*/

Voir aussiSee Also