|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Feb 2002
Città: Cassino (FR)
Messaggi: 274
|
C# Se son classi referenzieranno...
Oggi ho scoperto un'altro poco della mia ignoranza.
Vado a spiegare cosa mi opprime. Io ho una classe banale: Codice:
public class Hello { private int x = 0; public Hello() { } public int Ics { get { return this.x; } set { this.x = value; } } } Codice:
Hello m_hello = new Hello(); m_hello.Ics = 5; Formetto m_frm = new Formetto(); // Si assuma che .Dati sia una proprietà object del form m_frm.Dati = m_hello; m_frm.ShowDialog(this); Codice:
// On Load Hello m_frmhello = (Hello)this.Dati; m_frmhello.Ics = 10; this.Close(); Questo comportamento fa presuppore un passaggio per ref o out, quando io invece non ho mai chiesto una cosa del genere!! Invece passando a .Dati un oggetto di tipo non classe, ovvero int, string.. etc.. questo passaggio per referenza non avviene, ovvero il mio valore resta bello pacioso sul 5. Ora, perchè accade questo? E c'è un sistema per evitarlo, oltre che fare un deep Clone della classe prima di passarglila a .Dati? Grazie un miliardo o forse più
__________________
![]() |
![]() |
![]() |
![]() |
#2 |
Member
Iscritto dal: Apr 2006
Messaggi: 53
|
Ciao, di default (cioè senza specificare ref o out) il tipo di dato passato a funzione in c# è di tipo ByVal (per chi conosce VB) : viene cioè eseguita una copia in memoria della variabile passata.
Per i value type ciò non ti permetterà di mutare il loro valore all'interno della funzione. Per i tipi oggetto invece qualsiasi assegnazione ai membri interni della classe avrà effetto ma non ti sarà permesso modificare il riferimento stesso alla variabile (es. settando a null l'oggetto). Scusa se non sono stato molto chiaro... è un concetto non molto semplice da spiegare a parole :-) Qui lo spiegano sicuramente meglio! Ciao! |
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Quando assegni una variabile ad un'altra variabile, ne copi il contenuto ma nel caso di variabili di tipo "reference", quello che copi è il reference (il riferimento all'oggetto), non l'oggetto stesso. Quindi nel tuo caso, m_hello e m_frm.Dati fanno riferimento alla stessa identica istanza della classe Hello.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Feb 2002
Città: Cassino (FR)
Messaggi: 274
|
Grazie ad entrambi, sì avevo dimenticato di leggere il capitolo su i tipi.
![]() E' una cosa abbastanza noiosa, in quanto per le classi di mamma Microsoft il metodo Clone è quasi sempre disponibile, mentre a me tocca implementarlo e per classi belle toste è una bella scocciatura. Sarebbe stato bello anche per il C# implementare una sorta di ByVal per passare una copia dell'oggetto. Affidandosi alla copia pari pari di memoria magari, senza sapere ne leggere ne scrivere.
__________________
![]() |
![]() |
![]() |
![]() |
#5 | ||
Member
Iscritto dal: Apr 2006
Messaggi: 53
|
Quote:
Quote:
Se le tue classi non necessitano di ereditare da altri oggetti crea un classe base che esegua (tramite la reflection) il deep clone del tuo oggetto. Ho cercato velocemente e ho trovato un esempio qui : Deep Clone In questo modo non dovrai implementare manualmente su ogni tuo oggetto un custom clone (che comportebbe sicuramente a problemi di gestione futura in quanto tutte le volte che aggiungi membri interni di tipo reference devi ricordarti di implementarli nella clone). |
||
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Feb 2002
Città: Cassino (FR)
Messaggi: 274
|
Ma sei un.. un... un grande
![]() Grazie un miliardo o forse due
__________________
![]() |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 06:42.