ByRef ByVal The Mistery

Un petit post suite à des petits problèmes rencontrés dernièrement avec les fameux ByVal, ByRef en vb.net.

 

Commençons par un exemple simple avec un type bien célèbre du Framework : String:

 

 

 

Jusqu'ici pas de soucis, pour un type du Framework ByVal travaille bien sur les valeurs et ByRef sur la référence de l'objet.

 

Maintenant, essayons avec un type perso : Une classe toute simple et bien connue :

  

 

 

Et recommençons le coup du ByVal, ByRef :

 

 

Dans cet exemple, on se rend compte que le ByVal n'est pas respecté et qu'il se comporte comme un ByRef.

 

Après un petit tour dans la MSDN et comme diraient certains :  RTFMSDN ;), il est clairement noté dans la doc MSDN que pour un type personnel le ByVal modifie la référence de l'objet et non une copie de celui_ci.

  

 

La solution ici passe par l'implémentation de Icloneable :

 

 (thx Aurél)

 

 La méthode Clone() renvoit une nouvelle instance identique (en terme de valeurs) à mon objet et par conséquent le ByVal se passe bien étant sur une référence distincte :

 

Voilà pour la première partie.

 

J'ai voulu pousser le bouchon un peu plus loin en rajoutant une petite méthode à ma classe Personne qui attend un argument en ByRef et je vais appeler celle-ci dans une assembly C# :

 

Je rajoute ici, une méthode qui permet de changer son nom avec un string passé en référence :

 

 

Lorsque que j'essai d'appeler ma méthode dans la classe C# voici l'erreur :

 

 

 

Petite vue dans l'explorateur d'objet :

 

#Update : Petite rectification (Merci Jb) :

Jb said : "En C#, avec une méthode avec un paramètre en ref ou en out, il faut préfixer l'argument a l'appel de la fonction".

#End Update

 

Impossible :s !!! Alors, de vb.net à C# ça ne passe pas, je tente alors l'inverse : C# to vb.net, je recommence en créant une jolie classe ;) Ordinateur que voici :

 

Je compile celle-ci et l'appelle dans un programme VB.net, et là CA MARCHE :s

 

 

 

 

 

Si vous avez une explication à ceci, vos feedbacks sont les bienvenues :))

 

#Update 23/08

J'en profite pour rajouter qq liens sur le sujet :

 

Copying, Cloning, and Marshalling in .NET

http://www.ondotnet.com/pub/a/dotnet/2002/11/25/copying.html

 

C# Programmer's Reference
Passing Parameters

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vclrfpassingmethodparameters.asp

 

#End Update

 

Dubrow

Anakin of Wygwam

 

 

Publié lundi 22 août 2005 23:28 par dubrow
Classé sous
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

# re: ByRef ByVal The Mistery @ mardi 23 août 2005 02:11

Rien d'anormal.
En C#, avec une méthode avec un paramètre en ref ou en out, il faut préfixer l'argument a l'appel de la fonction:

per1.ChangeToRefName (ref newName);

La ça compilera.
Ensuite, passer des strings en ref, comme de toute façon les strings CLR sont immuables, ça va créer une nouvelle instance quand même.

dubrow

# re: ByRef ByVal The Mistery @ mardi 23 août 2005 06:23

oui... en C#, il existe ces trois keywords : in, out, ref (in et out)

dubrow

# re: ByRef ByVal The Mistery @ mardi 23 août 2005 09:48

Thx Jb ;)

dubrow

# re: ByRef ByVal The Mistery @ mardi 23 août 2005 10:01

...
lol

dubrow

# re: ByRef ByVal The Mistery @ mardi 23 août 2005 10:44

un petit conseil

Ca vaut toujours le coup, temps à autre de faire du c# puis du VB et de les mixer.

Ca entretient la forme et facilite les transitions

Quoi qu'en dise les extemistes du C# ou du VB.Net

Bref, il faut connaitre les 2 pour mieux les exploiter plutot que les comparer

IMHO ;)

dubrow

# re: ByRef ByVal The Mistery @ mardi 23 août 2005 10:53

Je suis bien d'accord avec vous Comtesse ;), je ne cherchais pas ici à comparer mais plutot à utiliser les deux dans des projets distincts.

dubrow

# re: ByRef ByVal The Mistery @ mardi 23 août 2005 11:04

JB : "Ensuite, passer des strings en ref, comme de toute façon les strings CLR sont immuables, ça va créer une nouvelle instance quand même. "

Je ne suis pas sûr de de tesuivre. Passer des String 'en ref' permet de modifer sa valeur dans la fonction et après la fonction.

Immuable ca veut globalement dire que même si le type String est du type référence sa valeur n'est pas modifiable, en gros ca se comporte comme un value type.

dubrow

# re: ByRef ByVal The Mistery @ mardi 23 août 2005 11:43

sv>

Le passage par "référence" du .net est assez tricky.

On distingue plusieurs cas:

Les types valeurs, qui sont donc alloués sur la pile, ici, seront réellement passés par référence à la fonction. Donc on pourra observer le changement de valeur à partir de la méthode appellante.

Les types références, cad tous les autres types... Eux sont donc alloués sur le tas, et quoi qu'il en soit, toujours passés par référence. Le ref ici n'est qu'un trick, pour pouvoir réaffecter l'objet. En gros, ça va passer un pointeur sur un pointeur.

Et donc ce qui nous intéresse ici, le type string, appartient donc à la seconde catégorie. Cependant, c'est un type qui sera géré de manière spéciale par la runtime. Chaque modification d'un string alloue un nouveau string, et on manipulera une nouvelle référence donc. D'où le immuable.

dubrow

# re: ByRef ByVal The Mistery @ mardi 23 août 2005 12:05

jb, sur le fond, je suis ok, mais un point important qui ne me semble pas clair dans ton explication :

C'est qu'une String passée en "ref" sera modifiée dans la fonction et en sortie de fonction.

Es tu ok sur ce code : la sortie du Debug.WriteLine(hello) sera "hello ca va" ?

private void changeString()
{
string hello = "hello";
addString(ref hello);
Debug.WriteLine(hello)
}

private addString (ref string str)
{
str+=" ca va";
}

dubrow

# re: ByRef ByVal The Mistery @ mardi 23 août 2005 12:33

Oui bien sur.
La précision que j'apportais, concerne la ligne:

str+=" ca va";

Quoi qu'il en soit, que le paramètre soit passé en ref ou pas, il y aura ici une nouvelle instanciation d'un string. Ce n'est pas une réelle concaténation.

Pour plus de clareté, il y a toujours la msdn.

dubrow


Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01