TOC

This article has been localized into French by the community.

Classes:

Propriétés

Dans l'article précédent, nous avons parlé des champs. Ils sont comme des variables globales pour une classe, vous permettant leur accès dans toutes les méthodes. Nous avons aussi brièvement évoqué le fait que l'on peut accéder aux champs depuis d'autres classes s'ils sont identifiés comme public, mais cela n'est généralement pas recommandé. Pour les variables/champs auxquels vous voudriez avoir accès depuis l'extérieur de votre classe, vous devriez plutôt utiliser les propriétés.

Quand vous déclarez un champ comme public, vous y donnez un accès complet depuis l'extérieur - d'autres classes pouvant en faire ce qu'elles veulent, sans autre notification à la classe déclarante. Les Propriétés rendent le contrôle à la classe déclarante, en spécifiant qu'un champ est en lecture ou en écriture seule et permet à la classe déclarante de vérifier et manipuler sa valeur avant de la renvoyer ou de l'assigner au champ.

Une propriété ressemble un peu à un hybride de champ et de méthode, parce qu'en plus d'être déclaré comme un champ avec sa visibilité, son type de donnée, il dispose aussi d'un contenu, comme une méthode, pour en contrôler le comportement.

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

Notez les mots-clés get et set. Ils sont utilisés exclusivement pour les propriétés, pour contrôler le comportement lors de la lecture (get'in) et de l'écriture (set'in) du champ. Vous pouvez avoir des propriétés implémentant seulement la lecture ou seulement l'écriture, pour créer des propriétés en lecture seule ou en écriture seule, et vous pouvez même contrôler la visibilité des implémentations get et set, par exemple pour créer une propriété qui puisse être lue depuis n'importe où (public), mais modifiée uniquement depuis l'intérieur de la classe déclarante (private).

Vous noterez aussi que je fais référence à un champ nommé _name. Vous aurez également à déclarer cela dans votre classe, de sorte que votre propriété puisse l'utiliser. Un format communément admis pour les champs et propriétés ressemblera à ceci :

private string _name = "John Doe";

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

Vous pouvez maintenant voir comment le champ et la propriété fonctionnent ensembles: La méthode get va retourner la valeur du champ _name, alors que la méthode set va assigner la valeur qui a été donnée au champ _name. Dans la méthode set, on utilise le mot clé spécial value qui, dans ce cas, vas référer à la valeur passée à la propriété.

Donc, c'est à peu près aussi basique que possible et à ce stade, nous ne faisons rien qui ne puisse être accompli avec un simple champ public. Mais à un stade ultérieur, vous pouvez décider que vous souhaitez prendre plus de contrôle sur la façon dont les autres classes peuvent travailler avec le nom et puisque vous l'avez implémenté en tant que propriété, vous êtes libre de modifier l'implémentation sans déranger quiconque utilise votre classe. Par exemple, la propriété Name pourrait être modifiée pour ressembler à ceci:

private string _name = "John Doe";

public string Name
{
	get 
	{
		return _name.ToUpper();
	}
	set 
	{
		if(!value.Contains(" "))
			throw new Exception("Please specify both first and last name!");
		_name = value; 
	}
}

La méthode get impose désormais que la valeur renvoyée soit toujours en MAJUSCULES, quelle que soit la casse du champ de sauvegarde (_name). Dans la méthode set, nous avons ajouté un quelques lignes de code pour vérifier si la valeur passée contient un espace, car nous avons décidé que le nom doit toujours être composé à la fois d'un prénom et d'un nom - si ce n'est pas le cas, une exception est levée. Tout cela est très grossier et simplifié, mais cela devrait illustrer le niveau de contrôle total que vous obtenez lorsque vous utilisez des propriétés.

Propriétés en lecture seule

La plupart des propriétés que vous verrez dans les exemples de ce didacticiel seront à la fois lisibles et inscriptibles, car c'est l'utilisation la plus courante des propriétés, mais cela ne doit pas toujours être le cas. Tout d'abord, vous pouvez déclarer une propriété avec seulement une méthode-get, comme ceci :

private string _name = "John Doe";

public string Name
{
	get { return _name; }
}

Dans ce cas, vous ne pouvez plus modifier la propriété "Name" - vous pouvez seulement la lire et le compilateur émettra une erreur si vous essayez de lui attribuer une valeur. Cependant, vous pouvez toujours modifier la valeur de cette propriété à l'intérieur de la classe, puisque vous pouvez simplement attribuer une nouvelle valeur au champ "_name". En procédant de cette manière, on annule l'un des principaux avantages des propriétés : la possibilité de toujours contrôler si une valeur peut être acceptée. Comme nous l'avons déjà dit, la méthode set est un excellent moyen d'effectuer la validation de la valeur, mais si vous attribuez une nouvelle valeur au champ _name à partir de plusieurs endroits, parce que la propriété est en lecture seule, vous n'obtenez par cette validation.

Heureusement pour nous, C# offre une solution à ce problème : Vous pouvez définir une méthode set sur la propriété, mais limiter sa visibilité, en utilisant par exemple le mot-clé private ou protected. Vous obtiendrez ainsi le meilleur des deux mondes, puisque vous pourrez toujours attribuer une valeur à la propriété depuis l'intérieur de la classe (ou de toute classe héritée si vous utilisez le mot-clé protected) et la faire valider en conséquence. Voici un exemple :

private string _name = "John Doe";

public string Name
{
	get { return _name; }

	private set
	{
		if(IsValidName(value))
			this._name = value;
	}
}

public bool IsValidName(string name)
{
	return name.EndsWith("Doe");

}

La principale différence ici est simplement le mot clé "private" juste devant le mot clé "set", et comme mentionné, vous pouvez le remplacer par, par exemple, protected ou internal, selon vos besoins.

Propriétés auto-implémentées

Dans certains cas, vous n'avez pas besoin de tout le contrôle d'un champ et il peut être fastidieux d'implémenter à la fois un champ et une propriété avec les méthodes get et set qui ne font rien d'autre que ce que nous avons vu dans le premier exemple. Vous pourriez être tenté de déclarer simplement votre variable comme un champ public pour éviter tous ces tracas supplémentaires. Mais ne faites pas cela ! Heureusement pour nous tous, Microsoft a décidé d'ajouter des propriétés auto-implémentées dans la version 3 de C#, ce qui vous permettra d'économiser plusieurs lignes de code. Voyez la différence :

Propriété ordinaire avec des champs déclarés :

private string _name;

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

Le même comportement, mais avec une propriété auto-implémentée :

public string Name { get; set; }

Remarquez que les méthodes get et set sont vides et qu'aucun champ de sauvegarde privé n'est déclaré - en d'autre termes, nous pouvons maintenant obtenir exactement le même comportement que dans le premier exemple, mais avec une seule ligne de code ! Gardez à l'esprit que le champ d'accompagnement privé existera toujours au moment de l'exécution - il sera auto-implémenté par le compilateur, comme son nom l'indique. Si vous décidez plus tard que vous avez besoin de plus de contrôle sur cette propriété spécifique, vous pouvez simplement la transformer en une combinaison normale champ/propriété avec l'implémentation souhaitée des méthodes get et set.

Notez que vous disposez toujours d'un mécanisme de contrôle important par rapport aux propriétés ordinaires lorsque vous utilisez des propriétés auto-implémentées : Vous pouvez omettre le mot clé set pour créer une propriété en lecture seule, par exemple comme ceci :

public string ReadOnlyProperty { get; }

Les propriétés en écriture seule ne sont pas autorisées lorsqu'on utilise des propriétés auto-implémentées.

Propriétés auto-implémentées avec valeur par défaut

Avant la version 6 de C#, vous ne pouviez pas définir une valeur par défaut pour une propriété auto-implémentée. Pour cela, vous deviez déclarer un champ complémentaire, ce qui vous permettait d'initialiser la variable avec une valeur :

private string _name = "John Doe";

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

Mais dans la version 6 de C#, Microsoft a enfin ajouté la possibilité d'initialiser une propriété auto-implémentée avec une valeur par défaut, comme ceci :

public string Name { get; set; } = "John Doe";

Propriétés de l'expression corporelle

Une autre fonctionnalité liée aux propriétés que Microsoft a implémentée dans C# 6.0 et 7.0 est le corps d'expression des membres. Elle vous permet simplement d'écrire des expressions d'une seule ligne pour vos propriétés et méthodes - dans ce cas, voyons comment l'utiliser pour vos méthodes get/set d'une manière qui prendre moins de place et nécessite un peu moins de saisie :

private string name;
public string Name
{
	get => name;
	set => name = value;
}

Si votre propriété est en lecture seule, la syntaxe peut-être encore plus courte :

public string Name => "John Doe";

Bien sûr, cela fonctionne aussi si vous devez faire quelque chose avant de renvoyer la valeur, comme ceci :

public string Name { get; set; } = "John Doe";

public string FirstName => this.Name.Substring(0, this.Name.IndexOf(" "));

Comme vous pouvez le voir, cela vous permet de définir une méthode get sans le mot clés get et return, tout en vous encourageant à garder tout cela sur une seule ligne au lieu de plusieurs.

Résumé

Les propriétés octroient à vos classes plus de contrôle sur la manière dont les champs peuvent être accédés et manipulés, et elles doivent toujours être utilisées lorsque vous souhaitez donner accès à des champs en dehors de la classe déclarante.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!