Programmation C sharp/Propriétés et indexeurs
Les propriétés
modifierUne propriété est une valeur qui peut être lue ou modifiée, comme une variable.
Ces deux opérations sont en fait réalisées par les accesseurs get
et set
. Si l'un de ces deux accesseurs est manquant, la propriété sera alors soit en lecture seule, soit en écriture seule.
Syntaxe
modifierType Nom_de_la_propriété { get // propriété lue { code retournant une valeur du Type spécifié } set // propriété modifiée { code utilisant le paramètre prédéfini "value" } }
Le code contenu dans chaque bloc est le même que celui que l'on placerait pour implémenter les méthodes suivantes :
Type getNom_de_la_propriété() { code retournant une valeur du Type spécifié } void setNom_de_la_propriété(Type value) // propriété modifiée { code utilisant le paramètre prédéfini "value" }
Exemple
modifierprivate string _message;
public string Message
{
get
{
return _message;
}
set
{
_message = value;
}
}
Utilisation :
Message = "Test de la propriété" ; // <- accesseur set
Console.WriteLine( Message ); // <- accesseur get
Message += " et message ajouté"; // <- accesseurs get et set
Noms réservés
modifierDepuis la version 2003 du compilateur, lorsqu'une propriété est créée, deux noms de méthodes sont réservés pour les deux accesseurs :
type get_Nom_propriété()
void set_Nom_propriété(type value)
La classe ne peut donc avoir de méthodes portant l'une de ces deux signatures.
Accesseurs simplifiés
modifierUne propriété en lecture seule possède un accesseur de lecture get mais aucun accesseur d'écriture set, comme dans l'exemple suivant :
private string _message;
public string MessageSize
{
get
{
return _message.Length();
}
}
Depuis C#6.0 il est possible de simplifier la définition d'une telle propriété : le nom de la propriété est directement associé à l'expression retournée par l'accesseur de lecture en utilisant l'opérateur =>
.
private string _message;
public string MessageSize => _message.Length();
Depuis C#7.0 il est possible d'utiliser cette syntaxe sur les accesseurs, qui est donc applicable également à une propriété en lecture et écriture, comme illustré par cet exemple :
private string _message;
public string Message
{
get => _message;
set => _message = value;
}
Accesseurs auto-implémentés
modifierUne propriété peut également avoir des accesseurs auto-implémentées :
- La variable de stockage de la valeur n'a plus à être déclarée : elle est générée par le compilateur ;
- Dès que l'un des accesseurs est auto-implémenté, les autres doivent l'être également.
Exemple :
public class Test
{
public string Message { get; set; }
}
La classe n'ayant aucun constructeur explicite, l'initialisation d'un objet peut se faire en utilisant la syntaxe suivante permettant d'initialiser les propriétés :
Test test1 = new Test{ Message="Exemple de test"; };
test1.Message = "Autre test";
Accesseurs d'initialisation
modifierSelon les accesseurs définis pour une propriété :
- Celle ci est en lecture seule si seulement l'accesseur
get
est défini, - Ou en lecture-écriture quand les deux accesseurs
get
etset
sont définis.
Depuis C#9.0, il existe un cas intermédiaire permettant de définir une propriété qui devient en lecture seule après initialisation de l'objet, en déclarant un accesseur nommé init
.
Exemple :
public class Test
{
public string Message { get; init; }
}
L'accesseur init
est utilisé lors de l'initialisation de l'objet.
Test test1 = new Test{ Message="Exemple de test"; }; // <-- OK, appelle l'accesseur init
test1.Message = "Autre test"; // <-- ERREUR, pas d'accesseur set
Quand l'accesseur init
est implémenté, il peut servir à initialiser des champs readonly
de l'objet :
public class Test
{
private readonly string message;
public string Message
{
get => message;
init => message = (value ?? throw new ArgumentNullException(nameof(Message)));
}
public string MessageSize
{
get => message.Length();
}
}
Les indexeurs
modifierUn indexeur est une propriété spéciale qui permet d'utiliser une instance de la classe comme un tableau, en utilisant les crochets.
Syntaxe
modifierType_élément this[ Type_index index ] { get // élément [index] lu { Code retournant une valeur du Type_éléments spécifié dont l'index est dans le paramètre index } set // élément [index] modifié { Code utilisant le paramètre prédéfini "value" pour le stocker à l'index spécifié par le paramètre index } }
Type_élément
- Type de chaque élément du tableau virtuel.
Type_index
- Type de l'indice spécifié entre crochets.
index
- Variable contenant la valeur de l'indice de l'élément lu ou modifié.
L'index peut avoir un autre type que int
. C'est le cas des tables de hashage de l'espace de nom System.Collections
.
Exemple
modifierpublic class TableauVirtuel
{
public string this[int index]
{
// lecture seule car pas d'accesseur set
get
{
return "Elément"+index.ToString();
}
}
}
...
TableauVirtuel tab=new TableauVirtuel();
Console.WriteLine("tab[15] = " + tab[15] );
// affiche Elément15