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
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.
Bon, en fait, il semble que vous ne maitrisiez pas la différence entre les 2 :).
ByVal passe le contenu de la variable par valeur : la variable est recopiée. ByRef passe le une réfèrence vers la variable.
Qu'est ce que cela signifie ?
1) Dans le cas d'une structure (ou tout autre type valeur) Une variable d'un type valeur contient directement ses données. Si on passe une telle variable par valeur, on a alors une copie des données qui est effectuée et tout changement sur une des copies n'affecte pas l'autre. Exemple : structure MyStruct public MyData as string end structure
sub MyMethod1() { dim myValueVar as MyStruct myValueVar.MyData = "bonjour" MyMethod(myValueVar) Console.WriteLine(myValueVar.MyData) }
sub MyMethod2(ByVal MyStruct myParam) { myParam.MyData = "bonsoir" }
Cet exemple va afficher "bonjour", car myParam est une copie de myValueVar.
De même, si on fait : sub MyMethod2(ByVal MyStruct myParam) { myParam = new MyStruct() myParam.MyData = "bonsoir" } Aucune modification n'est répercutée sur sur myValueVar.
Si on utilise ByRef au lieu de ByVal : sub MyMethod2(ByRef MyStruct myParam) { myParam.MyData = "bonsoir" }
myParam devient une réfèrence vers myValueVar. Toute modification faîte sur myParam est répercutée sur myValueVar. Le texte affiché est donc bonsoir. De même, si on fait : sub MyMethod2(ByRef MyStruct myParam) { myParam = new MyStruct() myParam.MyData = "bonsoir" } Les modifications sont effectuées sur myValueVar : la première ligne réinitialise myValueVar à ses valeurs par défaut, la seconde affecte "bonsoir" à myValueVar.MyData.
Enfin si on a : function MyMethod2(ByVal MyStruct myParam) as MyStruct { myParam.MyData = "bonsoir" return myParam; }
et qu'on modifie l'appel : myValueVar = MyMethod2(myValueVar) myParam est une copie de myValueVar, une modification sur myParam n'est pas répercutée sur myValueVar. Cependant, à la sortie de la fonction, on affecte la valeur de myParam à myValueVar. Ca veut dire que myValueVar devient en fait une copie de myParam. Le texte affiché est donc bonsoir.
Une méthode Swap s'écrirait ainsi :
sub MyMethod() { dim myValueVar, myValueVar2 as MyStruct myValueVar.MyData = "bonjour" myValueVar2.MyData = "bonsoir" Swap(myValueVar, myValueVar2) }
sub Swap(ByRef param1 as MyStruct, ByRef param2 as MyStruct) { MyStruct tmp = param1 'tmp contient une copie de la structure référencée par param1. tmp est donc une copie de myValueVar param1 = param2 'la structure référencée par param1 (myValueVar) contient désormais une copie de la structure référencée par param2 (myValueVar2). myValueVar contient donc une copie de myValueVar2 param2 = tmp 'la structure référencée par param2 (myValueVar2) contient désormais une copie de tmp, lui même une copie de la valeur de myValueVar avant l'appel à la fonction. Le Swap est donc terminé. }
2) Maintenant, les classes (ou tout autre type réfèrence) Une variable d'un type référence ne contient pas directement ses données mais contient une réfèrence vers ses données. Si on passe une telle variable par valeur, on a alors une copie de la réfèrence qui est effectuée.
Exemple : class MyClass public MyData as string end structure
sub MyMethod1() { dim myValueVar as MyClass myRefVar= new MyClass() myRefVar.MyData = "bonjour" MyMethod(myRefVar) Console.WriteLine(myRefVar.MyData) }
sub MyMethod2(ByVal MyClass myParam) { myParam.MyData = "bonsoir" }
myParam contient une copie de la réfèrence de myRefVar; autrement dit myParam et myRefVar font tous les deux réfèrences au même objet et toute modification faîte sur l'objet est donc commune aux 2 réfèrences. Le code ci-dessus affiche donc bonsoir.
Si on fait : sub MyMethod2(ByVal MyClass myParam) { myParam = new MyClass(); myParam.MyData = "bonsoir" }
Aprés l'exécution de la première ligne, myParam est une réfèrence vers un nouvel objet différent de celui réfèrencé par myRefVar. Le code afficherait donc "Bonjour".
Si on utilise ByRef au lieu de ByVal : sub MyMethod2(ByRef MyClass myParam) { myParam.MyData = "bonsoir" } MyParam est une réfèrence vers myRefVar qui est une réfèrence vers des données. Autrement dit, myParam est une réfèrence vers une réfèrence vers des données. Dans l'exemple ci-dessus, on a aucun problème le texte affiché est bonsoir.
Si on fait : sub MyMethod2(ByRef MyClass myParam) { myParam = new MyClass() myParam.MyData = "bonsoir" }
LA première ligne signifie que Les données réfèrencées par MyParam deviennent une réfèrence vers un nouvel objet. Or, les données réfèrencées par myParam, c'est myRefVar. MyRefVar réfèrence donc un nouvel objet. le MyData de ce nouvel objet est ensuite mis à "bonsoir", le texte affiché est donc "bonsoir".
Une fonction de Swap s'écrit donc ainsi :
sub MyMethod() { dim myRefVar, myRefVar2 as MyClass myRefVar = new MyClass() 'myRefVar contient une réfèrence vers un objet : obj1 myRefVar2 = new MyClass() 'myRefVar2 contient une réfèrence vers un objet : obj2 myRefVar.MyData = "bonjour" myRefVar2.MyData = "bonsoir" Swap(myValueVar, myValueVar2) }
sub Swap(ByRef param1 as MyClass, ByRef param2 as MyClass) { MyClass tmp = param1 'tmp contient les donnéees réfèrencées par param1. tmp et myRefVar sont donc deux réfèrences vers obj1 param1 = param2 'Les données réfèrencées par param1 sont maintenant égales aux données réfèrencées par param2 : myRefVar contient désormais la même chose que myRefVar2, c'est à dire une réfèrence vers obj2 param2 = tmp 'et enfin les données réfèrencées par param1 sont maintenant égales à tmp : yRefVar2 est une réfèrence vers obj1. }
Si on faisait un passage par valeur : sub Swap(ByVal param1 as MyClass, ByVal param2 as MyClass) { MyClass tmp = param1 'tmp est une réfèrence vers obj1 param1 = param2 'param1 est une réfèrence vers obj2, mais ceci n'affecte pas myRefVar1 param2 = tmp 'param2 est une réfèrence vers obj1, mais ceci n'affecte pas myRefVar2 }
Les valeurs de param1 et param2 sont bien swappées, mais pas celles de myRefVar1 et de myRefVar2.
Bon j'espère que j'ai réussi à être clair et que je ne me suis pas trompé en écrivant ces explications.
-- Zazar
Bonjour,
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.
Bon, en fait, il semble que vous ne maitrisiez pas la différence entre les 2
:).
ByVal passe le contenu de la variable par valeur : la variable est recopiée.
ByRef passe le une réfèrence vers la variable.
Qu'est ce que cela signifie ?
1) Dans le cas d'une structure (ou tout autre type valeur)
Une variable d'un type valeur contient directement ses données.
Si on passe une telle variable par valeur, on a alors une copie des données
qui est effectuée et tout changement sur une des copies n'affecte pas
l'autre.
Exemple :
structure MyStruct
public MyData as string
end structure
sub MyMethod1() {
dim myValueVar as MyStruct
myValueVar.MyData = "bonjour"
MyMethod(myValueVar)
Console.WriteLine(myValueVar.MyData)
}
sub MyMethod2(ByVal MyStruct myParam) {
myParam.MyData = "bonsoir"
}
Cet exemple va afficher "bonjour", car myParam est une copie de myValueVar.
De même, si on fait :
sub MyMethod2(ByVal MyStruct myParam) {
myParam = new MyStruct()
myParam.MyData = "bonsoir"
}
Aucune modification n'est répercutée sur sur myValueVar.
Si on utilise ByRef au lieu de ByVal :
sub MyMethod2(ByRef MyStruct myParam) {
myParam.MyData = "bonsoir"
}
myParam devient une réfèrence vers myValueVar. Toute modification faîte sur
myParam est répercutée sur myValueVar. Le texte affiché est donc bonsoir.
De même, si on fait :
sub MyMethod2(ByRef MyStruct myParam) {
myParam = new MyStruct()
myParam.MyData = "bonsoir"
}
Les modifications sont effectuées sur myValueVar : la première ligne
réinitialise myValueVar à ses valeurs par défaut, la seconde affecte
"bonsoir" à myValueVar.MyData.
Enfin si on a :
function MyMethod2(ByVal MyStruct myParam) as MyStruct {
myParam.MyData = "bonsoir"
return myParam;
}
et qu'on modifie l'appel :
myValueVar = MyMethod2(myValueVar)
myParam est une copie de myValueVar, une modification sur myParam n'est pas
répercutée sur myValueVar. Cependant, à la sortie de la fonction, on affecte
la valeur de myParam à myValueVar. Ca veut dire que myValueVar devient en
fait une copie de myParam. Le texte affiché est donc bonsoir.
Une méthode Swap s'écrirait ainsi :
sub MyMethod() {
dim myValueVar, myValueVar2 as MyStruct
myValueVar.MyData = "bonjour"
myValueVar2.MyData = "bonsoir"
Swap(myValueVar, myValueVar2)
}
sub Swap(ByRef param1 as MyStruct, ByRef param2 as MyStruct) {
MyStruct tmp = param1 'tmp contient une copie de la structure référencée
par param1. tmp est donc une copie de myValueVar
param1 = param2 'la structure référencée par param1 (myValueVar)
contient désormais une copie de la structure référencée par param2
(myValueVar2). myValueVar contient donc une copie de myValueVar2
param2 = tmp 'la structure référencée par param2 (myValueVar2) contient
désormais une copie de tmp, lui même une copie de la valeur de myValueVar
avant l'appel à la fonction. Le Swap est donc terminé.
}
2) Maintenant, les classes (ou tout autre type réfèrence)
Une variable d'un type référence ne contient pas directement ses données
mais contient une réfèrence vers ses données.
Si on passe une telle variable par valeur, on a alors une copie de la
réfèrence qui est effectuée.
Exemple :
class MyClass
public MyData as string
end structure
sub MyMethod1() {
dim myValueVar as MyClass
myRefVar= new MyClass()
myRefVar.MyData = "bonjour"
MyMethod(myRefVar)
Console.WriteLine(myRefVar.MyData)
}
sub MyMethod2(ByVal MyClass myParam) {
myParam.MyData = "bonsoir"
}
myParam contient une copie de la réfèrence de myRefVar; autrement dit
myParam et myRefVar font tous les deux réfèrences au même objet et toute
modification faîte sur l'objet est donc commune aux 2 réfèrences.
Le code ci-dessus affiche donc bonsoir.
Si on fait :
sub MyMethod2(ByVal MyClass myParam) {
myParam = new MyClass();
myParam.MyData = "bonsoir"
}
Aprés l'exécution de la première ligne, myParam est une réfèrence vers un
nouvel objet différent de celui réfèrencé par myRefVar. Le code afficherait
donc "Bonjour".
Si on utilise ByRef au lieu de ByVal :
sub MyMethod2(ByRef MyClass myParam) {
myParam.MyData = "bonsoir"
}
MyParam est une réfèrence vers myRefVar qui est une réfèrence vers des
données. Autrement dit, myParam est une réfèrence vers une réfèrence vers
des données.
Dans l'exemple ci-dessus, on a aucun problème le texte affiché est bonsoir.
Si on fait :
sub MyMethod2(ByRef MyClass myParam) {
myParam = new MyClass()
myParam.MyData = "bonsoir"
}
LA première ligne signifie que
Les données réfèrencées par MyParam deviennent une réfèrence vers un
nouvel objet. Or, les données réfèrencées par myParam, c'est myRefVar.
MyRefVar réfèrence donc un nouvel objet.
le MyData de ce nouvel objet est ensuite mis à "bonsoir", le texte affiché
est donc "bonsoir".
Une fonction de Swap s'écrit donc ainsi :
sub MyMethod() {
dim myRefVar, myRefVar2 as MyClass
myRefVar = new MyClass() 'myRefVar contient une réfèrence vers un objet
: obj1
myRefVar2 = new MyClass() 'myRefVar2 contient une réfèrence vers un
objet : obj2
myRefVar.MyData = "bonjour"
myRefVar2.MyData = "bonsoir"
Swap(myValueVar, myValueVar2)
}
sub Swap(ByRef param1 as MyClass, ByRef param2 as MyClass) {
MyClass tmp = param1 'tmp contient les donnéees réfèrencées par param1.
tmp et myRefVar sont donc deux réfèrences vers obj1
param1 = param2 'Les données réfèrencées par param1 sont maintenant
égales aux données réfèrencées par param2 : myRefVar contient désormais la
même chose que myRefVar2, c'est à dire une réfèrence vers obj2
param2 = tmp 'et enfin les données réfèrencées par param1 sont
maintenant égales à tmp : yRefVar2 est une réfèrence vers obj1.
}
Si on faisait un passage par valeur :
sub Swap(ByVal param1 as MyClass, ByVal param2 as MyClass) {
MyClass tmp = param1 'tmp est une réfèrence vers obj1
param1 = param2 'param1 est une réfèrence vers obj2, mais ceci n'affecte
pas myRefVar1
param2 = tmp 'param2 est une réfèrence vers obj1, mais ceci n'affecte pas
myRefVar2
}
Les valeurs de param1 et param2 sont bien swappées, mais pas celles de
myRefVar1 et de myRefVar2.
Bon j'espère que j'ai réussi à être clair et que je ne me suis pas trompé en
écrivant ces explications.
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.
Bon, en fait, il semble que vous ne maitrisiez pas la différence entre les 2 :).
ByVal passe le contenu de la variable par valeur : la variable est recopiée. ByRef passe le une réfèrence vers la variable.
Qu'est ce que cela signifie ?
1) Dans le cas d'une structure (ou tout autre type valeur) Une variable d'un type valeur contient directement ses données. Si on passe une telle variable par valeur, on a alors une copie des données qui est effectuée et tout changement sur une des copies n'affecte pas l'autre. Exemple : structure MyStruct public MyData as string end structure
sub MyMethod1() { dim myValueVar as MyStruct myValueVar.MyData = "bonjour" MyMethod(myValueVar) Console.WriteLine(myValueVar.MyData) }
sub MyMethod2(ByVal MyStruct myParam) { myParam.MyData = "bonsoir" }
Cet exemple va afficher "bonjour", car myParam est une copie de myValueVar.
De même, si on fait : sub MyMethod2(ByVal MyStruct myParam) { myParam = new MyStruct() myParam.MyData = "bonsoir" } Aucune modification n'est répercutée sur sur myValueVar.
Si on utilise ByRef au lieu de ByVal : sub MyMethod2(ByRef MyStruct myParam) { myParam.MyData = "bonsoir" }
myParam devient une réfèrence vers myValueVar. Toute modification faîte sur myParam est répercutée sur myValueVar. Le texte affiché est donc bonsoir. De même, si on fait : sub MyMethod2(ByRef MyStruct myParam) { myParam = new MyStruct() myParam.MyData = "bonsoir" } Les modifications sont effectuées sur myValueVar : la première ligne réinitialise myValueVar à ses valeurs par défaut, la seconde affecte "bonsoir" à myValueVar.MyData.
Enfin si on a : function MyMethod2(ByVal MyStruct myParam) as MyStruct { myParam.MyData = "bonsoir" return myParam; }
et qu'on modifie l'appel : myValueVar = MyMethod2(myValueVar) myParam est une copie de myValueVar, une modification sur myParam n'est pas répercutée sur myValueVar. Cependant, à la sortie de la fonction, on affecte la valeur de myParam à myValueVar. Ca veut dire que myValueVar devient en fait une copie de myParam. Le texte affiché est donc bonsoir.
Une méthode Swap s'écrirait ainsi :
sub MyMethod() { dim myValueVar, myValueVar2 as MyStruct myValueVar.MyData = "bonjour" myValueVar2.MyData = "bonsoir" Swap(myValueVar, myValueVar2) }
sub Swap(ByRef param1 as MyStruct, ByRef param2 as MyStruct) { MyStruct tmp = param1 'tmp contient une copie de la structure référencée par param1. tmp est donc une copie de myValueVar param1 = param2 'la structure référencée par param1 (myValueVar) contient désormais une copie de la structure référencée par param2 (myValueVar2). myValueVar contient donc une copie de myValueVar2 param2 = tmp 'la structure référencée par param2 (myValueVar2) contient désormais une copie de tmp, lui même une copie de la valeur de myValueVar avant l'appel à la fonction. Le Swap est donc terminé. }
2) Maintenant, les classes (ou tout autre type réfèrence) Une variable d'un type référence ne contient pas directement ses données mais contient une réfèrence vers ses données. Si on passe une telle variable par valeur, on a alors une copie de la réfèrence qui est effectuée.
Exemple : class MyClass public MyData as string end structure
sub MyMethod1() { dim myValueVar as MyClass myRefVar= new MyClass() myRefVar.MyData = "bonjour" MyMethod(myRefVar) Console.WriteLine(myRefVar.MyData) }
sub MyMethod2(ByVal MyClass myParam) { myParam.MyData = "bonsoir" }
myParam contient une copie de la réfèrence de myRefVar; autrement dit myParam et myRefVar font tous les deux réfèrences au même objet et toute modification faîte sur l'objet est donc commune aux 2 réfèrences. Le code ci-dessus affiche donc bonsoir.
Si on fait : sub MyMethod2(ByVal MyClass myParam) { myParam = new MyClass(); myParam.MyData = "bonsoir" }
Aprés l'exécution de la première ligne, myParam est une réfèrence vers un nouvel objet différent de celui réfèrencé par myRefVar. Le code afficherait donc "Bonjour".
Si on utilise ByRef au lieu de ByVal : sub MyMethod2(ByRef MyClass myParam) { myParam.MyData = "bonsoir" } MyParam est une réfèrence vers myRefVar qui est une réfèrence vers des données. Autrement dit, myParam est une réfèrence vers une réfèrence vers des données. Dans l'exemple ci-dessus, on a aucun problème le texte affiché est bonsoir.
Si on fait : sub MyMethod2(ByRef MyClass myParam) { myParam = new MyClass() myParam.MyData = "bonsoir" }
LA première ligne signifie que Les données réfèrencées par MyParam deviennent une réfèrence vers un nouvel objet. Or, les données réfèrencées par myParam, c'est myRefVar. MyRefVar réfèrence donc un nouvel objet. le MyData de ce nouvel objet est ensuite mis à "bonsoir", le texte affiché est donc "bonsoir".
Une fonction de Swap s'écrit donc ainsi :
sub MyMethod() { dim myRefVar, myRefVar2 as MyClass myRefVar = new MyClass() 'myRefVar contient une réfèrence vers un objet : obj1 myRefVar2 = new MyClass() 'myRefVar2 contient une réfèrence vers un objet : obj2 myRefVar.MyData = "bonjour" myRefVar2.MyData = "bonsoir" Swap(myValueVar, myValueVar2) }
sub Swap(ByRef param1 as MyClass, ByRef param2 as MyClass) { MyClass tmp = param1 'tmp contient les donnéees réfèrencées par param1. tmp et myRefVar sont donc deux réfèrences vers obj1 param1 = param2 'Les données réfèrencées par param1 sont maintenant égales aux données réfèrencées par param2 : myRefVar contient désormais la même chose que myRefVar2, c'est à dire une réfèrence vers obj2 param2 = tmp 'et enfin les données réfèrencées par param1 sont maintenant égales à tmp : yRefVar2 est une réfèrence vers obj1. }
Si on faisait un passage par valeur : sub Swap(ByVal param1 as MyClass, ByVal param2 as MyClass) { MyClass tmp = param1 'tmp est une réfèrence vers obj1 param1 = param2 'param1 est une réfèrence vers obj2, mais ceci n'affecte pas myRefVar1 param2 = tmp 'param2 est une réfèrence vers obj1, mais ceci n'affecte pas myRefVar2 }
Les valeurs de param1 et param2 sont bien swappées, mais pas celles de myRefVar1 et de myRefVar2.
Bon j'espère que j'ai réussi à être clair et que je ne me suis pas trompé en écrivant ces explications.
-- Zazar
Zazar
> Bon j'espère que j'ai réussi à être clair et que je ne me suis pas trompé
en
écrivant ces explications.
Je m'aperçois que j'ai mélangé du C# et du VB.NET pour compliquer un peu :)
-- Zazar
> Bon j'espère que j'ai réussi à être clair et que je ne me suis pas trompé
en
écrivant ces explications.
Je m'aperçois que j'ai mélangé du C# et du VB.NET pour compliquer un peu :)