readonly (référence C#)

Le mot clé readonly est un modificateur qui peut être utilisé dans cinq contextes :

  • Dans une déclaration de champ, readonly indique qu’une affectation à destination d’un champ peut survenir uniquement dans le cadre de la déclaration ou dans un constructeur de la même classe. Un champ en lecture seule peut être affecté et réaffecté plusieurs fois dans la déclaration de champ et le constructeur.

    Un champ readonly ne peut pas être affecté après l’arrêt du constructeur. Cette règle a des implications différentes selon les types de valeur et les types de référence :

    • Étant donné que les types de valeur contiennent directement leurs données, un champ qui est un type de valeur readonly est immuable.
    • Étant donné que les types de référence contiennent une référence à leurs données, un champ qui est un type de référence readonly doit toujours faire référence au même objet. Cet objet peut ne pas être immuable. Le modificateur readonly empêche le remplacement de la valeur de champ par une autre instance du type référence. Toutefois, le modificateur n’empêche pas les données d’instance du champ d’être modifiées par le champ en lecture seule.

    Avertissement

    Un type visible de l’extérieur qui contient un champ en lecture seule visible de l’extérieur qui est un type de référence mutable peut être une faille de sécurité et peut déclencher l’avertissement CA2104 : « Ne pas déclarer de type référence mutable en lecture seule. »

  • Dans une readonly struct définition de type, readonly indique que le type de structure est immuable. Pour plus d’informations, voir la section readonly struct de l’article Types de structure.

  • Dans une déclaration de membre d’instance dans un type de structure, readonly indique qu’un membre d’instance ne modifie pas l’état de la structure. Pour plus d’informations, voir la section readonly membres d’instance de l’article Types de structure.

  • Dans un ref readonlyretour de la méthode, le modificateur readonly indique que la méthode retourne une référence et que les écritures ne sont pas autorisés pour cette référence.

Exemple de champ en lecture seule

Dans cet exemple, la valeur du champ year ne peut pas être modifiée dans la méthode ChangeYear, même si une valeur lui a été affectée dans le constructeur de classe :

class Age
{
    private readonly int _year;
    Age(int year)
    {
        _year = year;
    }
    void ChangeYear()
    {
        //_year = 1967; // Compile error if uncommented.
    }
}

Vous pouvez affecter une valeur à un champ readonly uniquement dans les contextes suivants :

  • Lorsque la variable est initialisée dans la déclaration, par exemple :

    public readonly int y = 5;
    
  • Dans un constructeur d’instance de la classe qui contient la déclaration de champ d’instance.

  • Dans le constructeur statique de la classe qui contient la déclaration de champ statique.

Ces contextes de constructeur sont aussi les seuls contextes dans lesquels il est possible de passer un champ readonly comme paramètre out ou ref.

Notes

Le mot clé readonly est différent du mot clé const. Un champ const ne peut être initialisé qu'au moment de la déclaration du champ. Un champ readonly peut être assigné plusieurs fois dans la déclaration de champ et dans un constructeur. C'est pourquoi, les champs readonly peuvent avoir des valeurs différentes en fonction du constructeur utilisé. De même, alors qu’un champ const est une constante au moment de la compilation, le champ readonly peut être utilisé pour des constantes au moment de l’exécution, comme dans l’exemple suivant :

public static readonly uint timeStamp = (uint)DateTime.Now.Ticks;
public class SamplePoint
{
    public int x;
    // Initialize a readonly field
    public readonly int y = 25;
    public readonly int z;

    public SamplePoint()
    {
        // Initialize a readonly instance field
        z = 24;
    }

    public SamplePoint(int p1, int p2, int p3)
    {
        x = p1;
        y = p2;
        z = p3;
    }

    public static void Main()
    {
        SamplePoint p1 = new SamplePoint(11, 21, 32);   // OK
        Console.WriteLine($"p1: x={p1.x}, y={p1.y}, z={p1.z}");
        SamplePoint p2 = new SamplePoint();
        p2.x = 55;   // OK
        Console.WriteLine($"p2: x={p2.x}, y={p2.y}, z={p2.z}");
    }
    /*
     Output:
        p1: x=11, y=21, z=32
        p2: x=55, y=25, z=24
    */
}

Dans l’exemple précédent, si vous utilisez une instruction telle que dans l’exemple suivant :

p2.y = 66;        // Error

vous obtenez le message d’erreur du compilateur :

Un champ readonly ne peut pas être assigné (sauf s'il appartient à un constructeur ou un initialiseur de variable)

Membres d'instance en lecture seule

Vous pouvez également utiliser le modificateur readonly pour déclarer qu’un membre d’instance ne modifie pas l’état d’une struct.

public readonly double Sum()
{
    return X + Y;
}

Remarque

Dans le cas d’une propriété en lecture/écriture, vous pouvez ajouter le modificateur readonly à l’accesseur get . Certains accesseurs get peuvent effectuer un calcul et mettre en cache le résultat, plutôt que simplement retourner la valeur d’un champ privé. L’ajout du modificateur readonly à l’accesseur get garantit que l’accesseur get ne modifie pas l’état interne de l’objet en mettant en cache un résultat.

Vous trouverez d’autres exemples dans la section readonly membres de l’instance de l’article Types de structure.

Exemple de retour ref readonly

Le modificateur readonly au niveau d’un ref return indique que la référence retournée ne peut pas être modifiée. L’exemple suivant retourne une référence à l’origine. Il utilise le modificateur readonly pour indiquer que les appelants ne peuvent pas modifier l’origine :

private static readonly SamplePoint s_origin = new SamplePoint(0, 0, 0);
public static ref readonly SamplePoint Origin => ref s_origin;

Le type retourné ne doit pas nécessairement être un readonly struct. Tout type pouvant être retourné par ref peut être retourné par ref readonly.

Exemple de référence de retour en lecture seule en lecture seule

Un ref readonly return peut également être utilisé avec des membres d’instance readonly sur des types struct :

public struct ReadonlyRefReadonlyExample
{
    private int _data;

    public readonly ref readonly int ReadonlyRefReadonly(ref int reference)
    {
        // _data = 1; // Compile error if uncommented.
        return ref reference;
    }
}

La méthode retourne essentiellement une référence readonly avec le membre de l’instance (dans ce cas, une méthode) étant readonly (impossible de modifier les champs d’instance).

spécification du langage C#

Pour plus d'informations, voir 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.

Vous pouvez également voir les propositions de spécification de langage :

Voir aussi