[C#] reference, pointeurs

Bon, ca fait un petit bout de temps que je code en C# maintenant. Rien de trépidant en soi, mais suffisament pour avoir taté un peu de tout. Depuis le début, je suis émerveillé par le fait que C# sache exactement où je veux en venir quand je lui passe des parametres dans mes fonctions. Aujourd’hui, j’en suis arrivé au stade où j’aimerais comprendre la magie du truc. J’explique :

Admettons que j’ai une appli, composée de deux Form. Le MainForm, qui lance l’appli et un autre (appelons-le ParamForm), qui va par exemple permettre à l’utilisateur de changer les parametres de l’appli. Admettons maintenant que mes parametres sont stockés à la barbare dans un Dictionnary<string, string> nommé parametres avec la key qui contient le nom du parametre, et la value… sa valeur. (c’est un exemple hein, c’est juste pour illustrer ma question, venez pas me faire du hors sujet sur le fait que c’est sale).

Au moment ou je souhaite afficher le form avec les parametres, je fais un truc du genre :

ParamForm pf = new ParamForm(parametres); pf.ShowDialog();

Avec le constructeur de ParamForm :

[code]private Dictionnary<string, string>parametres;
public Dictionnary<string, string> Parametres { get { return this.parametres; } }

public ParamForm(Dictionnary<string, string> parametres)
{
this.parametres = parametres;
}[/code]

Au début, j’avais imaginé qu’après mon pf.ShowDialog() y me faudrait faire un truc du genre this.parametres = pf.Parametres. Mais non ! Magie ! C# à compris comme un grand qu’en fait ca serait super cool qu’il passe non pas une référence de mon objet parametres, mais carrément un pointeur en douce sans que je me rende compte de rien. Moi ca m’arrange à fond d’ailleurs.

Là c’est le cas d’une classe, mais ca marche aussi avec des int par exemple. Tout ca c’est donc génial. Maintenant, admettons que je reve de faire une fonction Convert(), dans ParamForm, qui change les values de parametres pour les mettre dans un autre format, mais sans toucher aux valeurs de MainForm.parametres ? Comment je fais ? Et en fait, comment je sais que c# il balance une référence, un pointeur, whatever ? Accessoirement, je comprend pas super l’interet de rajouter un “out” ou un “ref” du coup.

Voyez le probleme ? Alors j’ai cherché sur le net, j’ai bien trouvé quelques trucs, mais rien qui m’a aidé à comprendre le binz. Ca manque de “je passe des parametres pour les nuls”, en fait. Mais j’aimerais vraiment comprendre. Si quelqu’un pouvais me faire un cours rapide pour les démeurés, ca serait super.

Merci B)

Alors alors…
Il s’agit la d’un concept hyper fondamental (et le plus souvent complètement inconnu ou du moins méconnu des autodidactes) : les objets de type valeur et de type référence.

En gros, en Dotnet, tu as 2 types d’objets.
Les types valeurs :
Il s’agit la des types primitifs (int, char, float etc.), et des structures que tu définies.
Les données de ces objets sont directement stockées dans la pile. Quand tu passes un objet de ce type en paramètre d’une méthode, tu effectues un passage par valeur.

Les types références :
Il s’agit de la plupart des types d’objets .Net : les classes.
Les données de ces objets sont stockées dans le tas, et le contenu de la pile n’est qu’une référence vers l’emplacement mémoire des données de cet objet.
Quand tu passes un objet de type référence à une méthode, tu effectues un passage par référence.

Je connais pas le c#, mais il doit exister un moyen de cloner un objet pour justement permettre ce genre de truc.
J’imagine que ça doit ressembler à pf.clone();
edit : hop

Pour ton cas, il te faut créer une nouvelle instance de dictionary qui sera une copie de ton premier dictionnaire :
this.parameters = new Dictionnary<string,string>(parametres);

[quote=“girafologue, post:4, topic: 29767”]Pour ton cas, il te faut créer une nouvelle instance de dictionary qui sera une copie de ton premier dictionnaire :
this.parameters = new Dictionnary<string,string>(parametres);[/quote]
merci girafologue, je vais explorer les pistes que tu me donne, mais je sens que je vais revenir avec d’autres question dans quelques jours (si c’est pas ce soir…) B)

Bon, ami bishop, si tu passais plus souvent sur IRC, je t’aurais expliqué ca de manière interractive (c’est plus marrant, et ca va plus vite)…

Donc, dotnet, tu as deux catégories de types. Les types qui dérivent de ValueType et les autres.

Mais quelquesoit la catégorie, le comportement par défaut du passage est toujours le même : la copie.

Dans le cas d’un ValueType (entier, flotant …), tu copies la valeur, c’est assez évident.

Dans les autres cas, tu copies une référence. Donc tu pointe toujours sur le même objet. Bref, au fond, sauf sur les ValueTypes, ca revient a manipuler des pointeurs (d’ailleurs, en Managed C++, on ne manipule quasi que des pointeurs).

Quelques exemples quand j’aurais l’estomac plein…