Property, avantages réels ?

Résolu
SharpMao Messages postés 1024 Date d'inscription mardi 4 février 2003 Statut Membre Dernière intervention 7 juin 2010 - 19 oct. 2006 à 09:26
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 - 1 nov. 2006 à 22:31
Hello,

On m'a posé une question récemment à laquelle j'ai été bien embêter pour répondre.

On présente souvent des exemples avec des propriétés simples :

private string _text=""
public string Text
{
get
{return _text;}
set
{_text=value;}
}

La question était : dans un cas aussi simple, quel est l'avantage réel de mettre Text comme property plutôt que de mettre public la variable ?
Dans un cas plus compliqué, ou si on ne veut pas de set, je peux comprendre, mais dans un cas simpliste comme celui-ci, le seul effet que je vois, est de ralentir un peu le programme.
Si vous pouviez me donner une bonne raison d'utiliser les properties dans des cas semblabes, j'aurai apris quelque chose aujourd'hui.

Merci à tous, SharpMao

18 réponses

sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
19 oct. 2006 à 09:41
c'est surtout un principe de la programmation objet.

on ne doit jamais exposer publiquement les membres d'une classe. Il faut pour cela exposer des accesseurs.

Sébastien FERRAND (
blog)
Consultant Indépendant
[Microsoft MVP Visual C#]
3
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
19 oct. 2006 à 09:47
Pourtant, c'est vrai que dans un cas aussi simple que celui de ton exemple, c'est pas si facile de trouver une utilité.
Mais j'adhère aux reponses des mes collegues, principe de prog objet.

Mais j'ai eu moins une utilité reelle en tete : DataBinding. On utilise les propriétés pour le binding, pas les champs.

Mx
MVP C# 
3
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
19 oct. 2006 à 10:00
Petit article sur MSDN sur le sujet.
Il m'avait pourtant sembler lire un jour qu'une variable public pouvait poser des problèmes de sécurité.
Ma mémoire me jouerait t'elle (déjà) des tours? 

<hr size="2" />-Blog-
3
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
19 oct. 2006 à 14:11
Property = appel de méthode, c'est donc forcement plus long à moins que le compilateur optimise et "inline" la méthode.

Dans certains cas je me passe des propriétés, surtout pour les structures.
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
19 oct. 2006 à 09:34
Salut,
Je ne connais pas les détails (malheureusement) mais il s'agit d'une question de sécurité... il ne faut en prinicipe pas exposer les variables au monde extérieur (c'est à dire, les rendre publique).
De plus, je ne pense pas qu'une Property soit plus lente...

Peut-être que quelqu'un d'autre pourra te donner un peu plus d'infos....

<hr size="2" />-Blog-
0
SharpMao Messages postés 1024 Date d'inscription mardi 4 février 2003 Statut Membre Dernière intervention 7 juin 2010 69
19 oct. 2006 à 10:48
Hello,

Merci pour vos réponses. Je retiens donc



<li>le principe de POO (oui, mais un principe se devrait d'avoir une raison solide)</li>
<li>Le DataBindimg</li>
<li>La sécurité ? Si quelqu'un retrouve un article à ce sujet, je suis preneur.</li>

Quant à la question de la vitesse, oui, c'est plus rapide d'accéder à une variable qu'à une propriété. J'ai fait le test suivant :



Class1

c1 =

new



Class1


();


Class2
c2 =

new



Class2


();


DateTime
dt1 =

DateTime


.Now;


for
(

int
i = 0; i <

int


.MaxValue; i++)
   c1.Count = i;


TimeSpan
ts1 =

DateTime


.Now - dt1;


DateTime
dt2 =

DateTime


.Now;


for
(

int
i = 0; i <

int


.MaxValue; i++)
   c2.Count = i;


TimeSpan
ts2 =

DateTime

.Now - dt2;



Class1 exposant sa variable Count, et Class2 ayant une propriété Count.

Résultat : 




<li>
ts1.TotalMilliseconds = 3642

</li>
<li>
ts2.TotalMilliseconds = 12302

</li>

Soit tout de même un coefficient de 3.38

Amicalement, SharpMao
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
19 oct. 2006 à 11:55
Je n'arrive pas du tout au même résultat (j'ai utilisé la classStopWatch pour les calculs)
Voici mes résultats :

Lecture
3830477304
3601111444
Ecriture
27614531672
27878963156

Les nombres représentent les ticks écoulés. Le premier chiffre avec la variable, le deuxième avec la property, une fois en lecture et une fois en écriture.

Constat (j'ai fait le teste quelque fois, et j'obtients des résultats similaires)

- La lecture semble plus rapide avec une Property
- L'écriture semble un peu plus lente avec la Property, mais le coefficient est très faible.

<hr size="2" />-Blog-
0
SharpMao Messages postés 1024 Date d'inscription mardi 4 février 2003 Statut Membre Dernière intervention 7 juin 2010 69
19 oct. 2006 à 12:15
Hello,


J'ai refait mon test en utilisant les Stopwatch.


J'ai même fait une boucle vide pour regarder le temps de la boucle elle-même. Et mes résultats sont toujours les mêmes, pire encore si on enlève le temps de la boucle :


Boucle vide : 13 * 10^9
Boucle variable : 17.4 *10^9
Boucle property : 42.5 *10^9

Donc, une fois enlevé le temps de la boucle, un rapport de 6.7!
Je ne sais pas où nos test diffèrent, mais différence il y a !

Amicalement, SharpMao
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
19 oct. 2006 à 12:31
Hum, comment t'as codé les deux classes?

    public class Class1
    {
        public string test = "salut";
    }


    public class Class2
    {
        private string _test = "salut";
        public string Test { get { return this._test; } set { this._test = value; } }
    }

Un rapport de quasiement 7x me paraît assez peu probable je dois dire...
Mais j'explique toutefois pas le fait que nos tests soient autant différents...










<hr size="2" />



-Blog-
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
19 oct. 2006 à 12:51
Hum, j'espère que tu as fait ton teste en démarrant l'exécutable et en ayant fait une compilation en mode release ?!

<hr size="2" />-Blog-
0
SharpMao Messages postés 1024 Date d'inscription mardi 4 février 2003 Statut Membre Dernière intervention 7 juin 2010 69
20 oct. 2006 à 08:48
Pour Bidou,

mon code est semblable au tien, à la différence que j'ai utilisé des int à la place des string.

Pour Lutinore,
Je pensais aussi que la différence de temps venait de ça. J'ai d'ailleurs donné un petit coup d'ildasm à mon code :

Variable :
.field public int32 Count

Property :




.method public hidebysig specialname instance int32






get_Count() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld int32 TestDivers.Class2::_count
IL_0006: ret
} // end of method Class2::get_Count


.method public hidebysig specialname instance void
set_Count(int32 'value') cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld int32 TestDivers.Class2::_count
IL_0007: ret
} // end of method Class2::set_Count


Donc clairement plus à faire dans le cas d'une propriété.

Enfin. J'ai tout de même eu un début de réponse à ma question grace à vous.
Merci

Amicalement, SharpMao
0
TMONOD Messages postés 256 Date d'inscription mardi 25 novembre 2003 Statut Membre Dernière intervention 6 novembre 2009 1
28 oct. 2006 à 12:14
Vous avez tout faux messieurs :
- d'abord, vu la rapidité des processeurs d'aujourd'hui on ne cherche plus à gagner la milliseconde
- Deuzio, les propriétés permettent de créer un niveau d'abstraction qui autorise de changer l'implémentation interne d'un objet sans obliger les utilisateurs de l'objet à s'adapter : ca s'appelle l'encapsulation.
- Par exemple, si votre objet travail avec une liste de strings , vous pouvez tres bien travailler en interne avec une List(of string) un arraylist ou tout autre chôse et n'exposer à l'utilisateur que les fonctions d'accès à cette liste (Item(...) , Add(), Count, delete....).
- Terzio, utiliser une property plutot qu'une variable publique permet de vérifier les contraintes sur les valeurs directement à l'endroit où la valeur est lu ou écrite.
- Quatrezio, Quand vous voulez faire du readonly déclarer votre variable en readonly, cela ne doit pas être une raison de créér une property avec seulement GET. On crée une property quand on veux masquer l'implémentation interne d'un objet.

Voila c'est à peu près tout.

Jcbé[^]
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
29 oct. 2006 à 04:53
"Vous avez tout faux messieurs :"


Heureusement que tu es là alors..



"- d'abord, vu la rapidité des processeurs d'aujourd'hui on ne cherche plus à gagner la milliseconde"

Si si, même ( surtout ) en code managé, un peu d'optimisation ça ne fait pas de mal.. Et puis on parlait du principe, on ne t'a pas demandé si on voulait ou pas gagner quelques millisecondes.



"- Deuzio, les propriétés permettent de créer un niveau d'abstraction qui autorise de changer l'implémentation interne d'un objet sans obliger les utilisateurs de l'objet à s'adapter : ca s'appelle l'encapsulation."


Oui oui le principe de la POO, ça été cité par Sebmafate et MorpionMx.



"- Terzio, utiliser une property plutot qu'une variable publique permet de vérifier les contraintes sur les valeurs directement à l'endroit où la valeur est lu ou écrite."


Oui mais là, la question portait clairement sur un cas de figure ou justement il n y a aucun test de contraintes ou de valeurs.



"- Quatrezio, Quand vous voulez faire du readonly déclarer votre variable en readonly, cela ne doit pas être une raison de créér une property avec seulement GET. On crée une property quand on veux masquer l'implémentation interne d'un objet."


Pourquoi on a dit le contraire !?



"Voila c'est à peu près tout."


Voila c'est ça..
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
29 oct. 2006 à 08:50
Merci Lutinore

En plus, on parlait simplement dans le cas de l'exemple simple proposé pa SharpMao, pas de l'avantage des propriétés tout court...

Mx
MVP C# 
0
TMONOD Messages postés 256 Date d'inscription mardi 25 novembre 2003 Statut Membre Dernière intervention 6 novembre 2009 1
29 oct. 2006 à 09:14
Ok. Je suis passé pour un c...
Mes plattes excuses Messieurs, je me retire donc sur la pointe des pieds.

Jcbé[^]
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
29 oct. 2006 à 09:20
J'irais pas jusque là ;)
Y'a juste certaines façons pour dire les choses.

Le fond du message est juste. Il manquait juste la forme  (Du moins pour ma part, je l'ai ressenti comme ca)

Mx
MVP C# 
0
TMONOD Messages postés 256 Date d'inscription mardi 25 novembre 2003 Statut Membre Dernière intervention 6 novembre 2009 1
29 oct. 2006 à 10:18
- Merci. Mais je persiste à préférer un programme bien fait et lisible même si il est plus lent. Mais bon, si tu fais du temps réél, la y a pas de doute il faut aller chasser la microseconde.
- Mais qui voudrait faire du temps réél en dotnet ?.
Je dois cependant avouer que je n'utilise pas ilsdam, et que mes utilisations de la plateforme sont purement "bureautique" et réseau. Je ne suis donc pas le mieux placé pour juger.

Quoi qu'il en soit,j'apprécie et respecte le franc parler et la passion qui vous anime !

Bonne continuation.




Jcbé[^]
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
1 nov. 2006 à 22:31
Salut,

J'arrive largement après la bataille, mais tant pis, je vais quand même donner mon avis ^^

C'est vrai que dans ce cas simple on ne voit pas forcément l'intérêt, et on pourrait s'arrêter aux pertes de temps causés par l'appel de méthode.

Mais au final pour moi la lisibilité, la continuité avec le restant du code (pour lequel les propriétés se "justifient") et surtout l'aspect évolution prédominent.
Et si dans la v2 on veut réagir à un changement de valeur du texte, effectuer un traitement quelconque dessus etc, on est bien embêtés avec notre champs :p (sans briser le code existant)
Il s'agit d'un membre exposé publiquement, comment faire la validation de la valeur qui s'impose sur un champs ? (je pense que ça rejoint en partie l'argument du problème de sécurité cité précédemment). Et si on se dit "pas besoin de validation là" et que par la suite on s'aperçoit qu'il s'agissait d'une énorme erreur, comment ajouter la validation sans briser le code existant si c'est un champs ?

Sinon, en vrac :
- on ne peut définir de champs dans une interface
- on ne peut surcharger un champs
- avec une propriété, on peut ajouter du code de debug, trace...
- j'aime les propriétés ! (ok, celui là ne compte pas :p)

Voilà, s'il y avait besoin d'un autre avis, c'est fait :p

Après pour tout ce qui est optimisation et différences en profondeur, j'avoue ne pas m'être pencher suffisamment sur le fond du sujet.

/*
coq
MVP Visual C#
CoqBlog
*/
0
Rejoignez-nous