OVH Cloud OVH Cloud

Byval ou byRef

13 réponses
Avatar
David Bouchard
Je cherche à savoir quel est la meilleure option des deux. J'ai une fonction
qui prend un type valeur (structure) comme argument et la, je me demande
qu'est-ce qui est le mieux entre passé la valeur byRef pour intéragir
directement sur celle-ci ou bien, la passé ByVal pour ensuite la retourner.
Par exemple, j'aurais créé une structure BiColor

public structure BiColor
dim Couleur1 as color
dim Couleur2 as color
end structure

et ensuite, je voudrais faire un traitement sur une variable de type BiColor
à l'aide d'une fonction comme ceci

Dim Val as BiColor
val.couleur1 = color.black
val.couleur2 = color.red

Traitement_Couleur(val) 'En la passant ByRef
ou
Val = Traitement_Couleur(val) 'En la passant ByVal

Public function Traitement_Couleur(byval Val as BiColor) as BiColor
Val.Couleur1 = Val.Couleur2
Val.Couleur2 = color.blue
return Val
end function

ou

Public Sub Traitement_Couleur(ByRef Val as BiColor)
Val.Couleur1 = Val.Couleur2
Val.Couleur2 = color.blue
end sub

Merci

David

10 réponses

1 2
Avatar
Zazar
Bonsoir,

Je cherche à savoir quel est la meilleure option des deux. J'ai une


fonction
qui prend un type valeur (structure) comme argument et la, je me demande
qu'est-ce qui est le mieux entre passé la valeur byRef pour intéragir
directement sur celle-ci ou bien, la passé ByVal pour ensuite la


retourner.

Si vous utilisez ByRef, la méthode va modifier directement votre structure,
si vous utilisez ByVal, la méthode va copier votre structure, modifier la
copie, écraser l'ancienne structure avec la copie. Bref, ByVal n'a aucun
avantage dans cette situation.

--
Zazar
Avatar
Bismark Prods
L'avantage de la sécurité !

"Zazar" a écrit dans le message
de news:%
Bonsoir,

> Je cherche à savoir quel est la meilleure option des deux. J'ai une
fonction
> qui prend un type valeur (structure) comme argument et la, je me demande
> qu'est-ce qui est le mieux entre passé la valeur byRef pour intéragir
> directement sur celle-ci ou bien, la passé ByVal pour ensuite la
retourner.

Si vous utilisez ByRef, la méthode va modifier directement votre


structure,
si vous utilisez ByVal, la méthode va copier votre structure, modifier la
copie, écraser l'ancienne structure avec la copie. Bref, ByVal n'a aucun
avantage dans cette situation.

--
Zazar




Avatar
Zazar
> L'avantage de la sécurité !



Vous pouvez détailler ce que vous entendez par là ?

--
Zazar
Avatar
Bismark Prods
Ca dépend du contexte évidemment ! mais si on imagine rien qu'au niveau des
threads ? Un membre partagé en référence n'offre pas une très bonne sécurité
d'intégrité. ... mais il y a d'autre contexte ou un byVal est plus
sécurisant !

"Zazar" a écrit dans le message
de news:41238b8a$0$27134$

> L'avantage de la sécurité !

Vous pouvez détailler ce que vous entendez par là ?

--
Zazar




Avatar
Zazar
> Ca dépend du contexte évidemment ! mais si on imagine rien qu'au niveau


des
threads ? Un membre partagé en référence n'offre pas une très bonne


sécurité
d'intégrité. ...


Il n'en offre pas moins qu'un membre passé (pas partagé :) ) par valeur :
dans les 2 cas si on appelle la méthode sans faire attention, on peut se
retrouver avec n'importe quoi.
Et en plus, dans le cas d'un contexte multithread, si on passe les
paramètres avec byref, on peut mettre le mécanisme de synchronisation dans
la méthode, alors que dans le cas d'un passage par valeur puis récupération
par valeur de retour, il faut penser à effectuer la synchronisation à chaque
appel de méthode.

mais il y a d'autre contexte ou un byVal est plus
sécurisant !



Lesquels ? :)

Ici, on est vraiment dans un cas typique où ByRef sert réellement. (Bon en
fait, il vaudrait peut-être mieux utiliser une classe et passer l'instance
par valeur, mais si l'OP a besoin d'utiliser une structure, c'est son
droit).
En fait le seul problème que je vois c'est que (contrairement au C#), on
peut appeler une méthode en passant un paramètre par réfèrence sans s'en
rendre compte. Et donc si c'est utilisé par un développeur qui ne fait pas
attention à ce qu'il fait, il peut y avoir des surprises.

--
Zazar
Avatar
David Bouchard
Donc, si je comprend bien, ça dépend tout simplement du contexte. Par
contre, si j'ai à traité des structures volumineuses en données, j'imagine
qu'il est plus efficace de jouer directement sur la structure même avec
ByRef plutot que de copier celle-ci avec ByVal.

David


"Bismark Prods" <xanaia#nospam#@urbanet.ch> a écrit dans le message de
news:%
Ca dépend du contexte évidemment ! mais si on imagine rien qu'au niveau


des
threads ? Un membre partagé en référence n'offre pas une très bonne


sécurité
d'intégrité. ... mais il y a d'autre contexte ou un byVal est plus
sécurisant !

"Zazar" a écrit dans le


message
de news:41238b8a$0$27134$
>
> > L'avantage de la sécurité !
>
> Vous pouvez détailler ce que vous entendez par là ?
>
> --
> Zazar
>
>




Avatar
Bismark Prods
Je suis d'accord avec vous... Je dis tous ca à cause du projet que je code
actuellement ( le nez en plein dedans) ... Comme j'ai dis dans un autre
post, j'en suis à + de 40000 lignes.

Et je ne me souviens pas de toutes les structures, fonctions, méthodes,
champs etc. C'est pour cette raison que je dis qu'il vaut mieux faire excès
de zèle et se prémunier au maximum en passant par valeur ainsi on ne risque
pas de faire une bétise. De toutes les manières, on peut toujours par la
suite optimiser. lol

Bonne soirée

Bismark
Avatar
Zazar
> Donc, si je comprend bien, ça dépend tout simplement du contexte. Par
contre, si j'ai à traité des structures volumineuses en données, j'imagine
qu'il est plus efficace de jouer directement sur la structure même avec
ByRef plutot que de copier celle-ci avec ByVal.



En fait, je vais être un peu plus complet.
Vous semblez comprendre la différence entre ByVal et ByRef, je ne vais pas y
revenir.

La première question qu'il faut se poser c'est à quoi sert une structure ?

Les principales différences entre une structure et une classe concernent les
performances (la première peut être stockée sur la pile lorsque c'est une
variable locale ou inlinée dans un tableau), et le comportement
(l'affectation se fait par copie pour la structure, une structure ne peut
pas être héritée, ...).
Si on choisit d'utiliser une structure, c'est forcément pour un de ces
points-là.
Si c'est pour le deuxième point, c'est AMA une erreur de conception : il
vaut mieux utiliser une classe et si nécessaire on lui fait implémenter
ICloneable, on la marque comme sealed, ...
Les structures ne servent donc qu'à optimiser les parties critiques du
programme. Alors doit-on utiliser ByVal ou ByRef ? Le premier étant plus
lent que le second, dans un contexte d'optimisation on choisira toujours
ByRef. Conclusion : ByVal est "inutile" pour les structures.

Qu'en est-il pour les classes ?
La question se porte alors sur la sémantique de la méthode et de son
paramètre.
Si on veut modifier le contenu de l'objet, alors ByRef est totalement
inutile puisque la classe est un type réfèrence. L'objet devra donc être
passé par valeur. (Rem : il faudrait ensuite se demander si la méthode
modifiant l'objet ne devrait pas être une méthode de la classe de l'objet).
Ici le paramètre n'est qu'un paramètre d'entrée de la fonction (In dans les
languages de description des algorithmes)
Par contre, si on veut utiliser une fonction qui renvoie plusieurs
résultats, alors ByRef est indiqué. Ces paramètres sont en fait des valeurs
de retour de la fonction. (En C#, on utiliserait le mot-clef out, tout comme
dans les LDA).
Et enfin, si on veut réellement modifier la variable de la fonction
appelante (exemple classique : une fonction Swap(ByRef obj1 as object, ByRef
obj2 as object)), là encore ByRef doit être utilisé. Là, les paramètres sont
des paramètres d'entrées et de sortie (In et Out; en C# on utiliserait le
mot-clef ref).

Voilà. J'espère que ça vous aidera à vous décider pour toutes les prochaines
fois.

--
Zazar
Avatar
David Bouchard
Mais si tu utilises ByVal ou ByRef pour une classe, le résultat sera le même
finalement puisque une classe est un type référence, non? Autrement dit, la
fonction Swap avec ByRef ou ByVal fonctionne dans les deux cas.
Honnêtement, je comprend très bien le principe mais j'ai beaucoup de
difficulté encore à comprendre pourquoi utiliser plus l'un que l'autre dans
certain cas. Au bout de la ligne, l'impression que cela me donne est tout
simplement que si, je peux utiliser ByRef au lieu de ByVal, la performance
est probablement meilleure.

Pour ce qui est de la différence entre structure et classe, la distinction
est très clair et je crois bien en faire un bon usage.

Merci de tes explications.

David

"Zazar" a écrit dans le message
de news:4123b9a5$0$26993$
> Donc, si je comprend bien, ça dépend tout simplement du contexte. Par
> contre, si j'ai à traité des structures volumineuses en données,


j'imagine
> qu'il est plus efficace de jouer directement sur la structure même avec
> ByRef plutot que de copier celle-ci avec ByVal.

En fait, je vais être un peu plus complet.
Vous semblez comprendre la différence entre ByVal et ByRef, je ne vais pas


y
revenir.

La première question qu'il faut se poser c'est à quoi sert une structure ?

Les principales différences entre une structure et une classe concernent


les
performances (la première peut être stockée sur la pile lorsque c'est une
variable locale ou inlinée dans un tableau), et le comportement
(l'affectation se fait par copie pour la structure, une structure ne peut
pas être héritée, ...).
Si on choisit d'utiliser une structure, c'est forcément pour un de ces
points-là.
Si c'est pour le deuxième point, c'est AMA une erreur de conception : il
vaut mieux utiliser une classe et si nécessaire on lui fait implémenter
ICloneable, on la marque comme sealed, ...
Les structures ne servent donc qu'à optimiser les parties critiques du
programme. Alors doit-on utiliser ByVal ou ByRef ? Le premier étant plus
lent que le second, dans un contexte d'optimisation on choisira toujours
ByRef. Conclusion : ByVal est "inutile" pour les structures.

Qu'en est-il pour les classes ?
La question se porte alors sur la sémantique de la méthode et de son
paramètre.
Si on veut modifier le contenu de l'objet, alors ByRef est totalement
inutile puisque la classe est un type réfèrence. L'objet devra donc être
passé par valeur. (Rem : il faudrait ensuite se demander si la méthode
modifiant l'objet ne devrait pas être une méthode de la classe de


l'objet).
Ici le paramètre n'est qu'un paramètre d'entrée de la fonction (In dans


les
languages de description des algorithmes)
Par contre, si on veut utiliser une fonction qui renvoie plusieurs
résultats, alors ByRef est indiqué. Ces paramètres sont en fait des


valeurs
de retour de la fonction. (En C#, on utiliserait le mot-clef out, tout


comme
dans les LDA).
Et enfin, si on veut réellement modifier la variable de la fonction
appelante (exemple classique : une fonction Swap(ByRef obj1 as object,


ByRef
obj2 as object)), là encore ByRef doit être utilisé. Là, les paramètres


sont
des paramètres d'entrées et de sortie (In et Out; en C# on utiliserait le
mot-clef ref).

Voilà. J'espère que ça vous aidera à vous décider pour toutes les


prochaines
fois.

--
Zazar






Avatar
Bismark Prods
L'idéal pour bien comprendre toutes les interactions, serait de connaitre le
compilateur parfaitement. Ainsi tu verrais ce qui se passe ! Tu peux aussi
décompiler ton code et voir la différence entre byval et byref... si tu
connais un peu le code assembleur ?


"David Bouchard" a écrit dans le message de
news:
Mais si tu utilises ByVal ou ByRef pour une classe, le résultat sera le


même
finalement puisque une classe est un type référence, non? Autrement dit,


la
fonction Swap avec ByRef ou ByVal fonctionne dans les deux cas.
Honnêtement, je comprend très bien le principe mais j'ai beaucoup de
difficulté encore à comprendre pourquoi utiliser plus l'un que l'autre


dans
certain cas. Au bout de la ligne, l'impression que cela me donne est tout
simplement que si, je peux utiliser ByRef au lieu de ByVal, la performance
est probablement meilleure.

Pour ce qui est de la différence entre structure et classe, la distinction
est très clair et je crois bien en faire un bon usage.

Merci de tes explications.

David

"Zazar" a écrit dans le


message
de news:4123b9a5$0$26993$
> > Donc, si je comprend bien, ça dépend tout simplement du contexte. Par
> > contre, si j'ai à traité des structures volumineuses en données,
j'imagine
> > qu'il est plus efficace de jouer directement sur la structure même


avec
> > ByRef plutot que de copier celle-ci avec ByVal.
>
> En fait, je vais être un peu plus complet.
> Vous semblez comprendre la différence entre ByVal et ByRef, je ne vais


pas
y
> revenir.
>
> La première question qu'il faut se poser c'est à quoi sert une structure


?
>
> Les principales différences entre une structure et une classe concernent
les
> performances (la première peut être stockée sur la pile lorsque c'est


une
> variable locale ou inlinée dans un tableau), et le comportement
> (l'affectation se fait par copie pour la structure, une structure ne


peut
> pas être héritée, ...).
> Si on choisit d'utiliser une structure, c'est forcément pour un de ces
> points-là.
> Si c'est pour le deuxième point, c'est AMA une erreur de conception : il
> vaut mieux utiliser une classe et si nécessaire on lui fait implémenter
> ICloneable, on la marque comme sealed, ...
> Les structures ne servent donc qu'à optimiser les parties critiques du
> programme. Alors doit-on utiliser ByVal ou ByRef ? Le premier étant plus
> lent que le second, dans un contexte d'optimisation on choisira toujours
> ByRef. Conclusion : ByVal est "inutile" pour les structures.
>
> Qu'en est-il pour les classes ?
> La question se porte alors sur la sémantique de la méthode et de son
> paramètre.
> Si on veut modifier le contenu de l'objet, alors ByRef est totalement
> inutile puisque la classe est un type réfèrence. L'objet devra donc être
> passé par valeur. (Rem : il faudrait ensuite se demander si la méthode
> modifiant l'objet ne devrait pas être une méthode de la classe de
l'objet).
> Ici le paramètre n'est qu'un paramètre d'entrée de la fonction (In dans
les
> languages de description des algorithmes)
> Par contre, si on veut utiliser une fonction qui renvoie plusieurs
> résultats, alors ByRef est indiqué. Ces paramètres sont en fait des
valeurs
> de retour de la fonction. (En C#, on utiliserait le mot-clef out, tout
comme
> dans les LDA).
> Et enfin, si on veut réellement modifier la variable de la fonction
> appelante (exemple classique : une fonction Swap(ByRef obj1 as object,
ByRef
> obj2 as object)), là encore ByRef doit être utilisé. Là, les paramètres
sont
> des paramètres d'entrées et de sortie (In et Out; en C# on utiliserait


le
> mot-clef ref).
>
> Voilà. J'espère que ça vous aidera à vous décider pour toutes les
prochaines
> fois.
>
> --
> Zazar
>
>
>
>




1 2