Home Page
Articoli
Tips & Tricks
News
Forum
Archivio Forum
Blogs
Sondaggi
Rss
Video
Utenti
Chi Siamo
Contattaci
Username:
Password:
Login
Registrati ora!
Recupera Password
Home Page
Stanze Forum
.NET Framework
Passaggio per parametri ref con matrici
domenica 31 maggio 2009 - 09.54
Elenco Threads
Stanze Forum
Aggiungi ai Preferiti
Cerca nel forum
sanfra
Profilo
| Junior Member
137
messaggi | Data Invio:
dom 31 mag 2009 - 09:54
Salve, io sin da quando ho iniziato a programmare in c++, il passaggio per paramteri, se dovevo fare dei cambiamenti alla variabile del metodo gli assegnavo il famoso puntatore, sia che fosse una variabile, sia un array,in c# ho notato che anche se non metto la parola chiave ref prima dell'array lo legge cmq, potete dirmi che cosa ancora tutt'oggi non ho capito bene della programmazione sui paramteri passati per riferimento?
Grazie
P.S.:mi basterebbe anche un link!
aiedail92
Profilo
| Expert
993
messaggi | Data Invio:
dom 31 mag 2009 - 10:36
Ciao
Quello che succede avviene per un semplice motivo (che, dato che conosci il c++, non ti sarà difficile comprendere):
In .net ci sono due tipi di dati: le strutture e le classi, che si distinguono per un'importante differenza: le strutture sono un value type, mentre le classi sono un reference type. In altre parole, le strutture sono come le strutture e le classi del c++, mentre le classi equivalgono ai puntatori. Il valore di una classe non è l'oggetto stesso, ma un indirizzo in cui l'oggetto effettivo risiede.
Ora, poiché l'array è una classe e non una struttura, quando passi un array ad una funzione puoi modificare i valori degli elementi anche senza usare la ref, infatti quello che viene "duplicato" e passato alla funzione non è l'oggetto stesso, ma un puntatore che punta allo stesso oggetto.
Se, invece di un array, passassi un int (che è un value type) senza la ref, non potresti modificarne il valore (o meglio potresti ma alla funzione chiamante non cambierebbe) perché quello che viene passato è una copia dell'int, e quello che modificheresti sarebbe solo la copia. Usando la ref potresti modificare il valore restituendolo alla funzione chiamante.
Riassumendo, senza ref puoi modificare i membri di un reference type ma non il puntatore stesso (perché quello viene copiato), e non puoi modificare il valore di un value type; con la ref puoi modificare i membri e il puntatore di un reference type, e puoi modificare il valore di un value type.
Spero sia abbastanza chiaro, se ci sono dubbi chiedi pure
Luca
sanfra
Profilo
| Junior Member
137
messaggi | Data Invio:
dom 31 mag 2009 - 12:24
Innanzitutto grazie per il tuo intervento, ma quest'ultimo punto dove tu riassumi non mi è chiarissimo,che vuol dire che puoi modificare i membi di un reference type ma non il puntatore stesso(perchè quello viene copiato)?
>Riassumendo, senza ref puoi modificare i membri di un reference
>type ma non il puntatore stesso (perché quello viene copiato),
>e non puoi modificare il valore di un value type; con la ref
>puoi modificare i membri e il puntatore di un reference type,
>e puoi modificare il valore di un value type.
Comunque volevo capirlo meglio con degli esempi e se è possibile commentarli insieme.
Per esempio se io in una funzione:
void SomeTest(ref object[] valori) //in questo caso non avrebbe senso
se poi io creo una mia classe :
class Validator{
//proprietà
//membri
// costruttori
}
e in una funzione al di fuori di quest'ultima la richiamo così:
public void SomeTestClass(ref Validator v)// non ha senso neppure in questo modo.
Grazie ancora
tonyexpo
Profilo
| Senior Member
229
messaggi | Data Invio:
ven 19 giu 2009 - 18:39
Ciao
ti faccio un esempio
tipo valore (structure)
void test(int i)
{
//se cambi i non cambia nel chiamante
}
void test(ref int i)
{
//se cambi i cambia anche nel chiamante
}
tipo riferimento (class)
void test(tipo o)
{
//se cambi il valore di o non cambia nel chiamante
//se cambi il valore di una proprietà di o questa è dell'oggetto puntato da o, e quindi del chiamante
}
void test(ref tipo o)
{
//se cambi o questo cambia nel chiamante
//se cambi una proprietà di o cambia nel chiamante
}
spero di essere stato chiaro
ciao
Antonio Esposito
MCTS .NET 3.5 WCF, .NET 2.0 Distributed applications
MCP .NET 3.5/2.0
sanfra
Profilo
| Junior Member
137
messaggi | Data Invio:
sab 20 giu 2009 - 10:42
Ciao tonyexpo e grazie anche per la tua spiegazione,
sinceramente pensavo di aver capito,ma adesso tu mi hai dato delle delucidazioni in più.
Volevo chiederti sull'esempi da te riportati in particolare questo:
//se cambi il valore di una proprietà di o questa è dell'oggetto puntato da o, e quindi del chiamante
questo vuol dire che anche se non posto ref davanti all'oggetto e cambio una proprietà all'interno della funzione il chiamante avrà comunque la proprietà dell'oggetto modificata?
//void function(Oggetto o){
o.nome="Prova";
}
txtnome.Text=o.nome;
la text avrà Prova
Corretto?
Grazie
tonyexpo
Profilo
| Senior Member
229
messaggi | Data Invio:
dom 21 giu 2009 - 11:13
esatto
la differenza in uno scenario reference-type (class)
è che passando il parametro per valore (byval in VB, default in c#) nn fai che copiare il puntatore
hai quindi una variabile puntatore all'oggetto nel chiamante
e una variabile puntatore all'oggetto nel tuo metodo
i puntatori sono diversi, ma puntano allo stesso oggetto quindi se su quello fai modifiche a proprietà o invochi metodi ke lo fanno
le ritroverai altrove
passando il parametro per riferimento (byref in VB, ref in c#) passi un puntatore al tuo puntatore
quindi la variabile nel metodo punta alla variabile fuori
puoi sempre modificare proprietà dell'oggetto puntato ovviamente
ma puoi anche riassegnare alla variabile altri valori e questi saranno altresì assegnati alla variabile chiamante
spero di esser stato comprensibile
ciao
Antonio Esposito
MCTS .NET 3.5 WCF, .NET 2.0 Distributed applications
MCP .NET 3.5/2.0
sanfra
Profilo
| Junior Member
137
messaggi | Data Invio:
dom 21 giu 2009 - 12:30
chiaro e comprensibile, però ancora mi manca da capire un cosa(sarà il caldo) e spero di non annoiarti(o annoiare gli utenti di dotnethell),ed è la seduente:
a che scopo creare un oggetto che faccia riferimento ancora ad un oggetto, sarebbe il corrispondente in C++ di
void tipo(oggetto ** o)
Perchè fare così, sempre se è come sto cercando di capire?
se io ho un oggetto che chiamiamo "Cliente" e nella funzione : void Function(Cliente c), in che caso dovrei mettere il ref davanti se io so che è già un puntatore che la sua proprietà verrà comunque passata al chiamante modificata?
P.S.:Faccio questa supposizione, perchè ho visto un esempio del genere sulla rete e quindi mi ha un pò confuso.
Grazie ancora
tonyexpo
Profilo
| Senior Member
229
messaggi | Data Invio:
dom 21 giu 2009 - 13:02
>chiaro e comprensibile, però ancora mi manca da capire un cosa(sarà
>il caldo) e spero di non annoiarti(o annoiare gli utenti di dotnethell),ed
>è la seduente:
>
>a che scopo creare un oggetto che faccia riferimento ancora ad
>un oggetto, sarebbe il corrispondente in C++ di
>void tipo(oggetto ** o)
>
>Perchè fare così, sempre se è come sto cercando di capire?
>
>se io ho un oggetto che chiamiamo "Cliente" e nella funzione
>: void Function(Cliente c), in che caso dovrei mettere il ref
>davanti se io so che è già un puntatore che la sua proprietà
>verrà comunque passata al chiamante modificata?
l'unico caso è quando oltre la possibilità di modificarne le proprietà dell'oggetto, vuoi assegnare alla variabile chiamante una nuova istanza della stessa classe
es:
object o;
void assegnami(ref object o) {
o=new pippo();
}
>
>
>P.S.:Faccio questa supposizione, perchè ho visto un esempio del
>genere sulla rete e quindi mi ha un pò confuso.
>
>
>Grazie ancora
ciao
Antonio Esposito
MCTS .NET 3.5 WCF, .NET 2.0 Distributed applications
MCP .NET 3.5/2.0
sanfra
Profilo
| Junior Member
137
messaggi | Data Invio:
lun 22 giu 2009 - 12:38
grazie adesso mi è tuttio chiaro!
Torna su
Stanze Forum
Elenco Threads
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?
Dopo esserti registrato potrai chiedere
aiuto sul nostro
Forum
oppure aiutare gli altri
Consulta le
Stanze
disponibili.
Registrati ora !