TOC

This article is currently in the process of being translated into French (~52% done).

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 auc 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é.

So, this is pretty much as basic as it gets and at this point, we don't do anything that couldn't be accomplished with a simple public field. But at a later point, you may decide that you want to take more control of how other classes can work with the name and since you have implemented this as a property, you are free to modify the implementation without disturbing anyone using your class. For instance, the Name property could be modified to look like this:

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; 
	}
}

The get method now enforces that the value returned is always in UPPERCASE, no matter which case the backing field (_name) is in. In the set method, we have added a couple of lines of code to check whether the passed value contains a space, because we have decided that the name should always consist of both a first and a last name - if this is not the case, an exception is thrown. This is all very crude and simplified, but it should illustrate the full level of control you get when using properties.

Auto-implemented properties

In some cases, you don't need all the control over a field and it can feel cumbersome to implement both a field and a property with the get and set methods not doing anything besides what we saw in the first example. You may be tempted to simply declare your variable as a public field to avoid all this extra hassle. But don't do that! Fortunately for all of us, Microsoft decided to add auto-implemented properties in C# version 3, which will save you several lines of code. Just consider the difference:

Regular property with a declared backing field:

private string _name;

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

The exact same behavior, but with an auto-implemented property:

public string Name { get; set; }

Notice that the get and set methods are empty and that no private backing field is declared - in other words, we can now accomplish the exact same behavior as in the first example but with a single line of code! Bear in mind that the private backing field will still exist at runtime - it will be auto-implemented by the compiler, as the name implies. Should you later decide that you need more control of this specific property, you can simply change it to a regular field/property combination with the desired implementation of the get and set methods.

Notice that you are still left with an important mechanism of control from regular properties when using auto-implemented properties: You can leave out the set keyword to create a read-only property, e.g. like this:

public string ReadOnlyProperty { get; }

Write-only properties are not allowed when using auto-implemented properties.

Auto-implemented properties with default values

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";

Sommaire

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 souhaiter 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!