Programmation C sharp/Propriétés et indexeurs
Les propriétés
[modifier | modifier le wikicode]Une 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
[modifier | modifier le wikicode]Type 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
[modifier | modifier le wikicode]private 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
[modifier | modifier le wikicode]Depuis 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
[modifier | modifier le wikicode]Une 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
[modifier | modifier le wikicode]Une 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
[modifier | modifier le wikicode]Selon 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
[modifier | modifier le wikicode]Un indexeur est une propriété spéciale qui permet d'utiliser une instance de la classe comme un tableau, en utilisant les crochets.
Syntaxe
[modifier | modifier le wikicode]Type_é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
[modifier | modifier le wikicode]public 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