Propriétés vs méthodes

135

Question rapide: Quand décidez-vous d'utiliser des propriétés (en C #) et quand décidez-vous d'utiliser des méthodes?

Nous sommes occupés à avoir ce débat et avons trouvé des domaines où il est discutable de savoir si nous devrions utiliser une propriété ou une méthode. Un exemple est celui-ci:

public void SetLabel(string text)
{
    Label.Text = text;
}

Dans l'exemple, Labelest un contrôle sur une page ASPX. Existe-t-il un principe qui peut régir la décision (dans ce cas) d'en faire une méthode ou une propriété.

J'accepterai la réponse la plus générale et la plus complète, mais qui touche aussi l'exemple que j'ai donné.

Trumpi
la source
2
-1 cette question a été posée et a déjà reçu une réponse: stackoverflow.com/questions/164527/…
Élément
Les avantages et les inconvénients de la méthode / domaine / propriété peuvent générer de longs débats; une utilisation générale des propriétés: lorsque vous voulez des champs privés / protégés mais en même temps vous voulez les exposer. Une autre utilisation est d'avoir non seulement des instructions mais aussi des expressions (des actions si vous le souhaitez) même des if()vérifications (selon MSDN). Mais c'est délicat car l'utilisateur n'est pas toujours conscient du coût de traitement derrière l'accès à une variable (propriété) (c'est-à-dire que le code n'est pas disponible) et pour des raisons de rigueur, il faudrait comparer la propriété. Oh, et un "bonus", vous ne pouvez pas utiliser de pointeurs avec des propriétés.
mireazma

Réponses:

146

Dans la section Choisir entre les propriétés et les méthodes des directives de conception pour le développement de bibliothèques de classes:

En général, les méthodes représentent des actions et les propriétés représentent des données. Les propriétés sont destinées à être utilisées comme des champs, ce qui signifie que les propriétés ne doivent pas être complexes sur le plan informatique ou produire des effets secondaires. Lorsqu'elle ne viole pas les consignes suivantes, envisagez d'utiliser une propriété plutôt qu'une méthode, car les développeurs moins expérimentés trouvent les propriétés plus faciles à utiliser.

Ken Browning
la source
3
Bien que je sois d'accord avec une grande partie de cela, je ne pense pas que la partie sur les effets secondaires soit correcte. Par exemple, "Couleur" est souvent une propriété d'un objet, et elle a des effets secondaires évidents (changer la couleur d'un objet). La modification des propriétés a pour effet secondaire évident de changer l'état de l'objet.
Erik Funkenbusch
46
Mystere Man changer de couleur est l'effet souhaité et non l'effet secondaire. L'effet secondaire est quelque chose qui n'est pas prévu dans l'action primaire.
Muhammad Hasan Khan
2
@Mystere Man: changer définitivement la couleur n'est pas un effet secondaire, je suis entièrement d'accord avec cette réponse
Ahmed Said
2
"Parce que les développeurs moins expérimentés trouvent les propriétés plus faciles à utiliser." - Comme je le vois, c'est la seule raison d'exposer des propriétés. Mais ai-je raison?
Tsabo du
2
Quelle est la différence entre l'implémentation interne d'une propriété et d'une méthode. Quelque chose est-il poussé dans la pile d'appels chaque fois qu'une propriété est utilisée? Sinon, comment est-il géré autrement?
Praveen
57

Oui, si tout ce que vous faites est d'obtenir et de définir, utilisez une propriété.

Si vous faites quelque chose de complexe qui peut affecter plusieurs membres de données, une méthode est plus appropriée. Ou si votre getter prend des paramètres ou si votre setter prend plus qu'un paramètre de valeur.

Au milieu se trouve une zone grise où la ligne peut être un peu floue. Il n'y a pas de règle absolue et différentes personnes seront parfois en désaccord sur le point de savoir si quelque chose doit être une propriété ou une méthode. L'important est simplement d'être (relativement) cohérent avec la façon dont vous le faites (ou comment votre équipe le fait).

Ils sont largement interchangeables mais une propriété signale à l'utilisateur que la mise en œuvre est relativement "simple". Oh et la syntaxe est un peu plus propre.

De manière générale, ma philosophie est que si vous commencez à écrire un nom de méthode qui commence par get ou set et prend zéro ou un paramètre (respectivement), alors c'est un candidat de choix pour une propriété.

cletus
la source
1
Voté à la baisse. Ce n'est pas correct. La complexité d'un getter ou d'un setter est encapsulée dans le code getter / setter. Sa complexité n'est pas du tout pertinente, ni si elle "affecte plusieurs membres de données" Il est vrai que des paramètres non standard ou multiples nécessiteront une méthode, mais sinon, cette réponse n'est pas exacte.
Hal50000
La première phrase explique tout. Bravo.
SWIIWII
13

Les propriétés sont un moyen d'injecter ou de récupérer des données à partir d'un objet. Ils créent une abstraction sur des variables ou des données au sein d'une classe. Ils sont analogues aux getters et setters en Java.

Les méthodes encapsulent une opération.

En général, j'utilise des propriétés pour exposer des bits de données uniques ou de petits calculs sur une classe, comme la taxe de vente. Qui est dérivé du nombre d'articles et de leur coût dans un panier.

J'utilise des méthodes lorsque je crée une opération, comme récupérer des données de la base de données. Toute opération comportant des pièces mobiles est candidate à une méthode.

Dans votre exemple de code, je l'envelopperais dans une propriété si je devais y accéder en dehors de sa classe contenant:

public Label Title 
{
   get{ return titleLabel;}
   set{ titleLabel = value;}
}

Définition du texte:

Title.Text = "Properties vs Methods";

Si je définissais uniquement la propriété Text du Label, voici comment je le ferais:

public string Title 
{
   get{ return titleLabel.Text;}
   set{ titleLabel.Text = value;}
}

Définition du texte:

Title = "Properties vs Methods";
Chuck Conway
la source
12

Si vous définissez une propriété réelle de votre objet, vous utilisez une propriété.

Si vous effectuez une tâche / fonctionnalité, vous utilisez une méthode.

Dans votre exemple, il s'agit d'une propriété définie en cours de définition.

Si toutefois, votre fonctionnalité était AppendToLabel, vous utiliseriez une méthode.

Jour de Robin
la source
11

En recherchant dans MSDN, j'ai trouvé une référence sur Propriétés vs Méthodes qui fournit de bonnes directives pour la création de méthodes:

  • L'opération est une conversion, telle que Object.ToString.
  • L'opération est suffisamment coûteuse pour que vous souhaitiez indiquer à l'utilisateur qu'il doit envisager de mettre en cache le résultat.
  • L'obtention d'une valeur de propriété à l'aide de l'accesseur get aurait un effet secondaire observable.
  • L'appel du membre deux fois de suite produit des résultats différents.
  • L'ordre d'exécution est important. Notez que les propriétés d'un type doivent pouvoir être définies et récupérées dans n'importe quel ordre.
  • Le membre est statique mais renvoie une valeur qui peut être modifiée.
  • Le membre renvoie un tableau. Les propriétés qui renvoient des tableaux peuvent être très trompeuses. Il est généralement nécessaire de renvoyer une copie de la matrice interne afin que l'utilisateur ne puisse pas modifier l'état interne. Ceci, associé au fait qu'un utilisateur peut facilement supposer qu'il s'agit d'une propriété indexée, conduit à un code inefficace.
Gavin Miller
la source
Je conviens que cela a du sens le cas échéant. Mais ai-je raison, que l'utilisation de propriétés via la liaison XAML dans WPF ne laisse pas d'autre choix que d'effectuer les actions appropriées dans le setter? (en particulier sur un nouveau SelectedItem pour ComboBoxes, ListBoxes, etc.)
Nicolas
9

Il suffit de regarder le nom même ... "Propriété". Qu'est-ce que ça veut dire? Le dictionnaire le définit de bien des manières, mais dans ce cas, "un attribut ou une qualité essentielle ou distinctive d'une chose" convient le mieux.

Pensez au but de l'action. En fait, modifiez-vous ou récupérez-vous "un attribut essentiel ou distinctif"? Dans votre exemple, vous utilisez une fonction pour définir une propriété d'une zone de texte. Cela semble un peu idiot, n'est-ce pas?

Les propriétés sont vraiment des fonctions. Ils se compilent tous vers getXXX () et setXXX (). Cela les cache simplement dans le sucre syntaxique, mais c'est le sucre qui donne une signification sémantique au processus.

Pensez aux propriétés comme les attributs. Une voiture a de nombreux attributs. Couleur, MPG, modèle, etc. Toutes les propriétés ne sont pas paramétrables, certaines sont calculables.

Pendant ce temps, une méthode est une action. GetColor doit être une propriété. GetFile () doit être une fonction. Une autre règle de base est que si cela ne change pas l'état de l'objet, alors ce devrait être une fonction. Par exemple, CalculatePiToNthDigit (n) doit être une fonction, car il ne modifie pas réellement l'état de l'objet Math auquel il est attaché.

C'est peut-être un peu décousu, mais cela revient vraiment à décider ce que sont vos objets et ce qu'ils représentent. Si vous ne savez pas si cela doit être une propriété ou une fonction, peut-être que cela n'a pas d'importance.

Erik Funkenbusch
la source
9

Symantiquement, les propriétés sont des attributs de vos objets. Les méthodes sont les comportements de votre objet.

L'étiquette est un attribut et il est plus logique d'en faire une propriété.

En termes de programmation orientée objet, vous devez avoir une compréhension claire de ce qui fait partie du comportement et de ce qui n'est qu'un attribut.

Voiture {couleur, modèle, marque}

Une voiture a des attributs Color, Model et Brand, donc cela n'a pas de sens d'avoir une méthode SetColor ou SetModel car symantiquement, nous ne demandons pas à Car de définir sa propre couleur.

Donc, si vous mappez le cas de propriété / méthode à l'objet réel ou que vous le regardez d'un point de vue symantique, votre confusion disparaîtra vraiment.

Muhammad Hasan Khan
la source
4

Un autre avantage important pour Properties est que la valeur de la propriété peut être vue dans Visual Studio pendant le débogage.

David Karlaš
la source
3

Je préfère utiliser les propriétés pour les méthodes d'ajout / ensemble avec 1 paramètre. Si les paramètres sont plus nombreux, utilisez des méthodes.

abatishchev
la source
3

Les propriétés ne doivent être que de simples ensembles et obtenir une doublure. Rien de plus et cela devrait vraiment être déplacé vers une méthode. Le code complexe doit toujours être dans les méthodes.

Neil Bostrom
la source
3

Je n'utilise que des propriétés pour l'accès aux variables, c'est-à-dire obtenir et définir des variables individuelles, ou obtenir et définir des données dans les contrôles. Dès que tout type de manipulation de données est nécessaire / effectué, j'utilise des méthodes.

Marcus L
la source
3

En termes de conception, les propriétés représentent les données ou les attributs de l'objet de classe, tandis que les méthodes sont des actions ou des comportements d'objet de classe.

Dans .Net, dans le monde, il y a d'autres implications de l'utilisation des propriétés:

  • Les propriétés sont utilisées dans la liaison de données, contrairement aux méthodes get_ / set_.
  • Propriétés utilisateur de sérialisation XML comme mécanisme naturel de sérilisation.
  • Les propriétés sont accessibles par le contrôle PropertyGrid et par ICustomTypeDescriptor interne , qui peut être utilisé efficacement si vous écrivez une bibliothèque personnalisée.
  • Les propriétés sont contrôlées par des attributs , on peut l'utiliser à bon escient pour concevoir des logiciels orientés aspect.

Idées fausses (IMHO) sur l'utilisation des propriétés:

  • Utilisé pour exposer de petits calculs: le bloc get de ControlDesigner.SelectionRules comporte 72 lignes !!
  • Utilisé pour exposer les structures de données internes: même si une propriété ne correspond pas à un membre de données interne, on peut l'utiliser comme propriété, si c'est un attribut de votre classe. Viceversa, même si c'est un attribut de vos propriétés de classe n'est pas conseillé, de renvoyer un tableau comme des membres de données (à la place, des méthodes sont utilisées pour renvoyer une copie complète des membres.)

Dans l'exemple ici, il aurait pu être écrit, avec une signification plus commerciale comme:

public String Title
{
    set { Label.Text = text; }
}
NileshChauhan
la source
2

Les propriétés sont vraiment sympas car elles sont accessibles dans le concepteur visuel du studio visuel, à condition qu'elles y aient accès.

Ils sont utilisés lorsque vous définissez et obtenez simplement une validation qui n'accède pas à une quantité significative de code. Attention, la création d'objets complexes lors de la validation n'est pas simple.

Toute autre méthode est la méthode préférée.

Ce n'est pas qu'une question de sémantique. L'utilisation de propriétés inappropriées commence à provoquer des bizarreries dans le concepteur visuel du studio visuel.

Par exemple, j'obtenais une valeur de configuration dans une propriété d'une classe. La classe de configuration ouvre en fait un fichier et exécute une requête SQL pour obtenir la valeur de cette configuration. Cela a causé des problèmes dans mon application où le fichier de configuration était ouvert et verrouillé par Visual Studio lui-même plutôt que par mon application car non seulement il lisait mais écrivait la valeur de configuration (via la méthode setter). Pour résoudre ce problème, je devais simplement le changer en méthode.

Jeremy Edwards
la source
1

Voici un bon ensemble de directives pour savoir quand utiliser les propriétés par rapport aux méthodes de Bill Wagner

  • Utilisez une propriété lorsque tout cela est vrai: les getters doivent être simples et donc peu susceptibles de lever des exceptions. Notez que cela n'implique aucun accès au réseau (ou à la base de données). L'un ou l'autre pourrait échouer, et par conséquent lèverait une exception.
  • Ils ne devraient pas avoir de dépendances les uns sur les autres. Notez que cela inclurait la définition d'une propriété et son affectation à une autre. (Par exemple, la définition de la propriété FirstName affecterait une propriété FullName en lecture seule qui a composé les propriétés prénom + nom implique une telle dépendance)
  • Ils doivent être réglables dans n'importe quel ordre
  • Le getter n'a pas d'effet secondaire observable. Notez que cette directive n'exclut pas certaines formes d'évaluation paresseuse dans une propriété.
  • La méthode doit toujours revenir immédiatement. (Notez que cela exclut une propriété qui effectue un appel d'accès à la base de données, un appel de service Web ou toute autre opération similaire).
  • Utilisez une méthode si le membre renvoie un tableau.
  • Les appels répétés au getter (sans code intermédiaire) doivent renvoyer la même valeur.
  • Les appels répétés au setter (avec la même valeur) ne devraient donner aucune différence par rapport à un seul appel.

  • Le get ne doit pas renvoyer une référence aux structures de données internes (voir l'élément 23). Une méthode peut renvoyer une copie complète et éviter ce problème.

* Tiré de ma réponse à une question en double.

Chris Ballance
la source
Les réponses les mieux notées et acceptées ici stackoverflow.com/a/1294189/1551 Pourquoi le vote négatif?
Chris Ballance
2
Je sais que je suis un peu en retard à la fête, mais ce vote défavorable est probablement dû au fait que vous avez copié-collé votre réponse. Par copier-coller, vous avez admis que cette question était essentiellement un double de l'autre. En tant que tel, vous devriez l'avoir signalé comme un doublon au lieu d'y répondre. Je recommande de consulter un article sur Meta pour savoir comment les questions en double doivent être traitées.
Joshua
0

C'est simple.

1: utilisez la propriété lorsque vous souhaitez que vos données soient validées avant d'être stockées dans le champ. Ainsi, de cette manière, la propriété assure l'encapsulation de vos champs. Parce que si vous laissez vos champs publics, l'utilisateur final peut attribuer toute valeur qui peut ou non être valide selon vos besoins commerciaux, comme l'âge doit être supérieur à 18. Donc, avant que la valeur ne soit stockée, le champ correspondant, nous devons vérifier sa validité. De cette manière, les propriétés représentent des données.

2: Utilisez la méthode lorsque vous souhaitez effectuer une action comme si vous fournissez des données en tant que paramètre et que votre méthode effectue un traitement sur la base des valeurs fournies et renvoie la valeur traitée en sortie. Ou vous voulez changer la valeur d'un champ par ce calcul. "De cette manière, la méthode représente l'action".

Le Martien
la source
-1

Je viens de Java et j'ai utilisé la méthode get .. set .. pendant un moment.

Quand j'écris du code, je ne me demande pas: "accéder à ces données est simple ou nécessite un processus lourd?" car les choses peuvent changer (aujourd'hui retrive cette propriété est simple, tomonrow peut nécessiter un certain processus ou un processus lourd).

Aujourd'hui, j'ai une méthode SetAge (int age) tomonrow, j'aurai également la méthode SetAge (date de naissance) qui calcule l'âge en utilisant la date de naissance.

J'ai été très déçu que la propriété de transformation du compilateur dans get and set ne considère pas mes méthodes Get ... et Set .. comme identiques.

Marco Staffoli
la source