Newsgroup: it.comp.dotnet
Titolo: clonare un oggetto

ho un problema ricorrente:
apro una finestra che gestisce dati memorizzati in un oggetto, li modifico, 
se premo ok li trasferisco in un oggetto della finestra chiamante, copiando 
uno ad uno i campi;
quando apro la finestra naturalmente devo fare il contrario.
Non è possibile creare una istanza di un oggetto e "clonarlo" con un altro 
esistente?
Grazie
 


L'oggetto è tuo e di conseguenza devi decidere tu la logica di 
clonazione.
Considerato che .net separa tra reference type e value type la 
differenza è bella grossa nella politica di cloning.
Se a quell'oggetto è collegato un grafo (in pratica sempre se un membro 
è un reference type), quanti livelli del grafo vuoi clonare?
Se il cloning lo implementi 'ad hoc' per quell'oggetto avrai la 
scocciata di scriverlo ma performance massime.
Se invece usi serializzazione e deserializzazione dell'oggetto 
(ISerializable, attributo Serializable, IXmlSerializable, 
NetDataContractSerializer,etc.) avrai poco da scrivere ma performance 
molto povere.
-- 
Raffaele Rialdi  
http://www.iamraf.net
Weblog: 
http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile 
https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET - 
http://www.ugidotnet.org/

 ha scritto nel messaggio 
news:mn.53ac7dac5...@n0spamvevy.com...


 comando.
no, non puoi farlo. La tecnica più vicina a quanto hai detto consiste 
nell'usare il BinaryFormatter per fare un dump dell'oggetto dentro un 
MemoryStream, e poi usare ancora il formatter per ottenere il "clone" a 
partire dallo stream. Ma è lento (vedi msg di Raf) ed insicuro (non 
tutto lo stato dell'oggetto potrebbe essere clonabile: dipende dalla sua 
implementazione)
-- 
.A
GUISA - 
http://www.guisa.org
UGIdotNET - 
http://www.ugidotnet.org
Read my blog at: 
http://blogs.ugidotnet.org/pape

 clone(oggetto_2, oggetto_1);
Oltre a quanto già detto da Andrea, cerca di farti un esempio in mente.
Che succede se uno dei membri della classe è un dataset. Il clone deve 
fare una copia completa di tutto il dataset che ci sta dietro (deep 
copy) oppure copiare solo il *reference* (shallow copy).
La decisione è enorme perché il grafo (dataset e altre classi in 
gerarchia) che ci stanno dietro potrebbero essere anche da gigabyte.
Tutto ciò che è reference type implica questa decisione, stringhe 
comprese che però sono "speciali" in quanto immutabili, di conseguenza 
deep o shallow fa poca differenza sul risultato (non sulla memoria 
occupata ovviamente).


 ha scritto nel messaggio 
news:mn.54397dac7...@n0spamvevy.com...


 clonabile...
Certo, e infatti questo è l'approccio dei serilizzatori binario e xml 
che permettono di stabilire la "forma" della serializzazione 
semplicemente decorando i membri della classe con attributi.
Peccato che tutto questo implichi l'uso di reflection e quindi 
abissalmente più lenta rispetto ad una soluzione ad-hoc che però pesa 
sul developer.
La soluzione per scrivere meno codice e avere le max performance può 
stare nel generare delle classi di clonazione in modo automatico, per 
esempio utilizzando i template T4 di visual studio. Ovviamente il modo 
in cui creare questi template è tutta da inventare (ma è anche il bello 
del nostro lavoro)


 ha scritto nel messaggio 
news:mn.5caf7dacc...@n0spamvevy.com...



Suppongo che tu stia lavorando in c#...
...perché se lavorassi in c++ sapresti dell'esistenza dei costruttori di 
copia e/o operatori di assegnamento...
In c++ in tanti casi il costruttore di copia ce l'hai gratis, ma nulla 
vieta di fartelo a manina anche in c#:
http://msdn.microsoft.com/en-us/library/ms173116(VS.80).aspx
Il vero svantaggio è che devi poi ricordarti di tenerlo "aggiornato" 
quando aggiungi eventuali campi...

 clone(oggetto_2, oggetto_1);
Per una shallow copy esiste Object.MemberwiseClone:
<
http://msdn.microsoft.com/en-us/library/
system.object.memberwiseclone.aspx>
Nei Remarks trovi alcune considerazioni su come implementare una deep
copy.
-LV

 ha scritto nel messaggio 
news:4d07b2d1$0$34301$4faf...@reader3.news.tin.it...


 si, in effetti la soluzione migliore,
Passare a C++?
:P
-LV