Contexte de la question
Les propriétés en Visual Basic permettent d'encapsuler la logique d'obtention et d'attribution de valeurs. Avec l'introduction des propriétés, le code devient plus lisible et sécurisé, éliminant la nécessité d'un accès direct aux champs de la classe et facilitant l'implémentation de la logique de validation ou de calcul directement dans les objets.
Problème
Les débutants ont souvent tendance à rendre un champ public ou à utiliser des propriétés automatiques sans getter/setter contenant la logique, ce qui entraîne une violation de l'encapsulation ou l'impossibilité d'implémenter des valeurs calculées. Un autre problème est l'appel récursif d'une propriété à l'intérieur d'elle-même, entraînant un StackOverflow.
Solution
En Visual Basic, un champ privé est déclaré, et la propriété inclut les blocs Get et Set avec la logique requise. Les propriétés calculées n'utilisent que Get, retournant une valeur calculée en fonction des champs privés. Dans le bloc set, il est toujours nécessaire d'accéder au champ privé pour éviter la récursion infinie.
Exemple de code:
Private _price As Decimal Private _quantity As Integer Public Property Total As Decimal Get Return _price * _quantity ' propriété calculée End Get End Property Public Property Price As Decimal Get Return _price End Get Set(value As Decimal) If value < 0 Then Throw New ArgumentException("Le prix doit être positif") _price = value End Set End Property
Caractéristiques clés:
Puis-je accéder à la propriété Name dans le bloc Set de Price, si elle est également implémentée via un champ privé ?
Oui, s'il est fait appel à une autre propriété (comme Name) dans le bloc set de la propriété Price, cela est acceptable, car les accès à différents champs privés ne provoquent pas de récursivité. Il faut éviter d'appeler soi-même : appeler Price à l'intérieur de Set Price provoquera une récursivité.
Exemple de code:
Public Property Name As String Get Return _name End Get Set(value As String) _name = value End Set End Property Public Property Price As Decimal Get Return _price End Get Set(value As Decimal) If Name Is Nothing Then _name = "default" _price = value End Set End Property
Que se passe-t-il si j'appelle cette propriété à nouveau à l'intérieur du bloc Get ?
Cela entraînera une récursivité infinie et un StackOverflow. Dans le bloc get, utilisez toujours le champ privé, sinon la propriété s'appellera elle-même.
Public Property Amount As Decimal Get Return Amount ' provoquera une récursivité infinie End Get Set(value As Decimal) _amount = value End Set End Property
Puis-je déclarer une propriété en écriture seule (WriteOnly) et pourquoi est-ce dangereux ?
Il existe des propriétés WriteOnly, mais il n'est pas recommandé de les utiliser, car l'objet perd la capacité de retourner une valeur, ce qui nuit à la lisibilité et à la prévisibilité. Si elle n'est nécessaire que pour l'écriture, il vaut mieux revoir l'architecture.
Private _secret As String Public WriteOnly Property Secret As String Set(value As String) _secret = value ' Il est possible d'écrire, mais pas d'obtenir. End Set End Property
Un programmeur a décidé de rendre le champ Price public et a travaillé directement avec celui-ci. En conséquence, Price devenait parfois négatif par erreur.
Avantages:
Inconvénients:
Un collègue a remplacé Price par une propriété avec un champ privé et une validation dans le bloc set, ce qui a empêché des valeurs incorrectes.
Avantages:
Inconvénients: