1. Propriétés automatiques
En C#, une propriété (property) c’est un truc entre un champ et une méthode. En gros, c’est du sucre syntaxique qui rend l’encapsulation super pratique. Tu accèdes à la propriété comme si c’était un champ normal, mais à l’intérieur, tu peux mettre n’importe quelle logique : vérif des données, modif d’autres champs, appel de méthodes, voire envoyer un e-mail à ta grand-mère (bon, ça, c’est pas conseillé). Dans la leçon précédente, on écrivait les propriétés à la main. Mais ça devient vite relou si t’as 100500 objets simples où tu veux juste un "getter" et un "setter" — sans logique particulière.
Voici venir les propriétés automatiques. Elles te débarrassent du code répétitif et laissent C# gérer le stockage de la valeur à ta place.
Avant : propriétés manuelles
Quand tu veux cacher un champ mais y accéder via une propriété, tu faisais souvent comme ça :
public class Dog
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
Ce genre de code, c’est le "boilerplate" par excellence. Et souvent, on n’a rien à rajouter dans ces get/set ! Juste donner l’accès — et basta.
Comment on fait maintenant
En C#, c’est devenu plus simple : plus besoin d’écrire les champs à la main — le compilateur s’en charge. Il suffit d’écrire :
public class Dog
{
public string Name { get; set; }
}
Et voilà. Tu peux lire et modifier la valeur de Name tranquille, et sous le capot, le compilateur crée un champ privé que tu ne peux pas toucher directement.
Mais qu’est-ce qui se passe vraiment derrière ? Quand tu écris public string Name { get; set; }, le compilateur crée automatiquement un champ caché genre Name__BackingField. À chaque accès à Name, il insère le getter ou le setter qu’il faut. Le champ lui-même, tu ne le vois pas dans le code, mais il existe — et avec la réflexion, tu peux même le trouver (mais ça, c’est une autre histoire).
Pourquoi c’est cool ? D’abord, c’est beaucoup plus court et t’évite de répéter la même chose. Ensuite, le code est plus clean : moins de bruit visuel, plus facile à lire et à maintenir. Et enfin, c’est plus safe — personne ne peut aller bidouiller les champs directement, tout passe par les propriétés.
2. Syntaxe des propriétés automatiques
La syntaxe est super simple :
public class Dog
{
public string Name { get; set; }
public int Age { get; set; }
}
Maintenant, notre Dog est bien plus concis ! On peut créer des objets et donner des valeurs comme d’hab :
Dog myDog = new Dog();
myDog.Name = "Buddy";
myDog.Age = 4;
Schéma
| Méthode | Syntaxe | Accès à la valeur |
|---|---|---|
| Champ | |
Accès direct |
| Propriété manuelle | |
Accès via get/set |
| Propriété auto | |
get/set + champ caché |
3. Customisation de l’accès : lecture seule, écriture seule
Lecture seule : get-only
Si tu veux que la propriété soit seulement lisible (genre un numéro d’enregistrement d’animal), tu peux la rendre accessible en lecture seule — tu mets juste get, et tu ne mets pas set, ou alors tu le mets en privé. Tu peux alors donner une valeur seulement dans le constructeur ou directement à la déclaration :
public class Dog
{
public string RegistrationCode { get; }
public Dog()
{
RegistrationCode = "DOG-001"; // On donne la valeur dans le constructeur
}
}
Maintenant, de l’extérieur, tu peux juste lire RegistrationCode, mais pas la modifier. Parfait pour protéger des données importantes contre les modifs accidentelles.
Autre option : set privé
public string Name { get; private set; }
Du coup, la propriété ne peut être modifiée qu’à l’intérieur de la classe (genre via une méthode ou le constructeur).
Écriture seule : mauvaise idée
En théorie, tu peux faire une propriété set-only (écriture seule), mais c’est super rare et franchement pas conseillé — imagine un objet qui agit comme un "trou noir" : tu peux y balancer des trucs, mais jamais les récupérer.
4. init-only setters
Petit historique
Avant, pour faire un objet immuable (immutable), il fallait écrire des propriétés get-only et donner les valeurs via le constructeur. OK, c’est pratique — mais pas toujours. Mais récemment, C# a introduit une nouvelle syntaxe : les propriétés init-only.
C’est quoi le principe du setter init ?
- Permet de donner une valeur à la propriété seulement à la création de l’objet (c.-à-d. dans le constructeur ou dans l’initialiseur d’objet).
- Après la création, la propriété devient lecture seule.
- Parfait pour les classes "presque immuables", DTO, configs, modèles.
public class Dog
{
public string Name { get; init; }
public int Age { get; init; }
}
Maintenant, on peut faire ça :
Dog dog = new Dog { Name = "Bobik", Age = 2 };
dog.Name = "Rex"; // Erreur ! Après création - lecture seule
On peut aussi donner les valeurs dans le constructeur :
public Dog(string name, int age)
{
Name = name;
Age = age;
}
Schéma : quand peut-on assigner ?
| Où assigner ? | { get; set; } | { get; private set; } | { get; init; } |
|---|---|---|---|
| En dehors de la classe, après création | ✅ | ❌ | ❌ |
| Dans le constructeur | ✅ | ✅ | ✅ |
| Dans l’initialiseur | ✅ | ❌ | ✅ |
| Dans la classe | ✅ | ✅ | ❌ (sauf dans le constructeur) |
5. Utilisation en pratique
Réécrivons notre classe Dog en utilisant des propriétés automatiques et init-only :
public class Dog
{
// Propriété assignable seulement à l’initialisation
public string Name { get; init; }
public int Age { get; init; }
// Propriété automatique pour l’état actuel
public bool IsHungry { get; set; }
// Méthode, actions du chien
public void Bark()
{
Console.WriteLine($"{Name} dit : Ouaf !");
}
}
Maintenant, on peut créer Dog comme ça :
Dog dog = new Dog { Name = "Buddy", Age = 3, IsHungry = true };
dog.Bark(); // affiche : Buddy dit : Ouaf !
dog.IsHungry = false; // cette propriété peut être modifiée après création
dog.Name = "Buddy"; // Erreur ! Propriété seulement pour l’initialisation
6. Propriétés automatiques avec valeurs par défaut
En C#, tout est fait pour te simplifier la vie. Tu peux même donner une valeur par défaut à la propriété :
public class Dog
{
public string Name { get; set; } = "SansNom";
public int Age { get; set; } = 0;
}
Ou avec init :
public class Dog
{
public string Name { get; init; } = "Chiot";
public int Age { get; init; } = 0;
}
Du coup, si tu ne précises pas Name à la création, ce sera "Chiot".
7. Propriétés automatiques avec différents niveaux d’accès
Tu peux faire en sorte qu’une propriété soit lisible et modifiable avec des modificateurs d’accès différents :
public class Dog
{
public string Name { get; private set; }
public int Age { get; private set; }
public Dog(string name, int age)
{
Name = name;
Age = age;
}
}
Ici, tu ne peux modifier le nom et l’âge que dans la classe Dog, par exemple dans les méthodes ou le constructeur.
Comparaison propriétés manuelles et automatiques
| Approche | Difficulté d’écriture | Contrôle dans set/get | Modifiabilité après création | Utilisation dans les modèles |
|---|---|---|---|---|
| Propriété manuelle | Long | Absolu | Tout type | Là où il faut de la logique |
| Propriété automatique | Court | Non | Tout type ou privé | Presque partout |
| init-only automatique | Court | Non | Seulement à la création | DTO, configs |
8. Erreurs typiques avec les propriétés
Erreur n°1 : essayer d’assigner une valeur à une propriété get-only en dehors du constructeur.
Si la propriété est déclarée seulement avec get, le compilateur ne te laissera pas la modifier ailleurs. Tu peux assigner seulement dans le constructeur ou à la déclaration. Si tu oublies — erreur de compilation.
Erreur n°2 : confusion entre champ et propriété.
Quand tu remplaces un champ classique par une propriété automatique, vérifie bien qu’il n’y a pas d’accès direct au champ ailleurs dans le code. Champ et propriété, c’est pas pareil, et si tu laisses des accès au champ, le compilateur va râler ou le programme va faire n’importe quoi.
Erreur n°3 : set privé sans comprendre les conséquences.
Si une propriété a un set privé, mais que tu essaies encore de lui assigner une valeur ailleurs — erreur. Ça arrive souvent par accident, surtout quand tu copies du code d’ailleurs. Vérifie toujours si le set est dispo là où tu veux l’utiliser.
GO TO FULL VERSION