...
Post by Raffaele Rialdi [MVP]Post by Giorgio#visto che io credevo di sapere la differenza che ci stà nella
chiamata ad un metodo con passaggio di parametro per valore e per
riferimento. E visto che oggi ho scoperto che questo funzionamento in C#
sembra
differente rispetto al C++ o anche al C (cioè quello che sapevo io),
Qual'è la differenza tra passaggio per valore e per riferimento in C#?
Enormemente differente da C/C++, e uno dei concetti principali del
framework (non è peculiare di C#)
Faccio una carrellata molto *grossolana e veloce*...
I tipi come hai scoperto sono due: valuetype e reftype.
* I valuetype sono struct, enum e tipi di base. Quando li passi come
argomento vengono *duplicati* e allocati sullo stack e questo è un dato
da tenere sempre a mente. Ci sono poi altre piccole differenze che lascio
a te da guardare su msdn alla voce struct del reference di C#. I valuetype
non sono soggetti alla Garbage Collection.
* I reftype sono tutto ciò che è una class, interface e delegate e sono
sempre allocati nell'heap. In sostanza li usi sempre tramite un puntatore
che è il reference. Quando li passi come parametro non fai altro che
passare il reference. I reftype sono soggetti alla Garbage Collection.
*Le casistiche nel passaggio parametri sono 4:*
- passare un valuetype by value: il tipo viene copiato; ogni modifica
locale non influisce il valore del chiamante
- passare un valuetype by reference: viene passato un puntatore al tipo;
ogni modifica locale è fatta in realtà sull'oggetto del chiamante
- passare un referencetype by value: il reference all'oggetto viene
duplicato localmente. I due reference puntano allo stesso oggetto, quindi
ogni metodo/proprietà che agisce sull'oggetto stesso modificherà
l'oggetto. La stringa non è mutabile e quindi apparirà come fossero due
oggetti distinti anche se non è così.
- passare un referencetype by reference: passi un riferimento del
reference (come il ** del C). Puoi cambiare il reference del chiamante.
Utile raramente, per lo più nelle chiamate PInvoke.
Infine è bene ricordare che quando un valuetype può essere boxato (per
esempio quando viene messo dentro un object) e questa è una operazione
molto costosa. L'inverso è l'unboxing (cioè il valuetype viene estratto
dall'object che lo contiene).
Post by Giorgio#GRAZIE a tutti quelli che vorrano dare il loro apporto per confortare
la mia amara scoperta odierna.
P.S. state attenti a non sbagliare anche voi però.
Perché mai amara? :) È una delle prime cose messe in evidenza nel Richter,
un libro immancabile.
E poi questa differenza è una salvezza ;)
--
Raffaele Rialdi
Microsoft .NET MVP http://mvp.support.microsoft.com -
http://italy.mvps.org UGIdotNET - User Group Italiano .NET
http://www.ugidotnet.org Weblog: http://blogs.ugidotnet.org/raffaele