+ Rispondi al messaggio
Visualizzazione dei risultati da 1 a 9 su 9

duplicare oggetto per valore e non per riferimento

  1. #1
    Salve a tutti, banale quesito già risolto tempo fa, ma che all'occorrenza risolsi ma non trovo nel codice.

    ho necessità di salvare una copia di un oggetto per memorizzare i dati iniziale, per cui con la dichiarazione seguente è dichiarata per riferimento e quindi modifica il contenuto successivamente.


    //Nodo è una classe base preparata da me;
    // NodoInt è l'oggetto che voglio copiare
    Nodo ElementoDaSalvare = NodoInt;
    

    Secondo gli help che ho consultato si dovrebbe risolvere così ma va in errore:

    // Questo è in errore, non riconosce il metodo Clone
    Nodo tempnodo = (Nodo)NodoInt.Clone();
    


    Quale è la procedura corretta per salvare un oggetto per valore?

    Grazie
    Sebastiano

  2. #2
    Sgrubak non è in linea Scribacchino
    "Va in errore" vuol dire poco...
    Ma la classe Nodo espone il metodo Clone che restituisce un altro nodo uguale a se stesso?

  3. #3
    Risolto, era un problema di banale Maiuscola e minuscola

    public Nodo Clone()
            {
                return (Nodo)this.MemberwiseClone();          
            }
    
    L'unico dubbio che mi viene è perchè il Clone lo devo mettere in ogni oggetto e non è un metodo è proposto dal framework, vista l'utilità, evitando un mare di codice..
    Grazie
    Sebastiano

  4. #4
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Quote Originariamente inviato da SebastianoFloridia Visualizza il messaggio
    L'unico dubbio che mi viene è perchè il Clone lo devo mettere in ogni oggetto e non è un metodo è proposto dal framework, vista l'utilità, evitando un mare di codice..
    Non è proposto dal framework perché non è detto che il "Clone" vada fatto allo stesso modo per tutti gli oggetti.

    Ad esempio, supponi che il tuo oggetto contenga una proprietà di tipo SqlConnection: questo valore nell'oggetto clonato va semplicemente "copiato", oppure è necessario creare una nuova connessione? In entrambi i casi, ci sono vantaggi ma anche problemi, a seconda del contesto.

    Il framework non può indovinare se intendi fare un clone dei soli dati, oppure se il clone di un oggetto complesso dovrebbe essere la risultante dell'operazione di "cloning" analoga di tutti gli oggetti che referenzia.

    E se poi vai a clonare un oggetto creando una copia mentre nel resto del codice hai passato in precedenza un rifermento alla copia originale?

    Gli scenari sono troppo variabili per poter implementare un Clone() che si adatti a qualsiasi situazione.

    Dovendolo implementare invece, le soluzioni a disposizione per scrivere poco codice sono tante: dalla serializzazione alla copia dei campi interni, ecc.

    Io comunque approfondirei l'argomento per verificare che tu non vada a incappare in nessuna situazione "spiacevole".

    Ciao!
    ℹ️ Leggi di più su _alka_ ...

  5. #5
    Grazie!!!
    Sostanzialmente serve per evitare 20 righe di codice per replicare le proprietà.

    Nodo tempnodoprima = (Nodo)NodoInt.Clone();
    
    dove:

      public class Nodo
        {
            public float X { get; set; }
            public float Y { get; set; }
            public float Z { get; set; }
            public string Tag { get; set; }
            public string[] Vincoli = new string[6];
    

    Mi rimane un dubbio:
    E' possibile che il clone funzioni solo per le proprietà principali e su vettore Nodo.Vincoli[6], invece rimane per riferimento.
    Succede una cosa strana.
    le proprietà principali non modificano, mentre i dati del vettore cambiano in funzione di NodoInt.
    Come se fosse metà per valore e metà per riferimento.

    Grazie
    Sebastiano Floridia

  6. Quote Originariamente inviato da SebastianoFloridia Visualizza il messaggio
    Grazie!!!
    ...
    Succede una cosa strana.
    ....
    Come se fosse metà per valore e metà per riferimento.
    ....
    documentati sulla differenza tra deep copy e shallow copy

    detto in breve :
    se hai due puntatori allo stesso oggetto (copia superficiale) puoi modificare lo stato
    dell'oggetto da entrambi i puntatori ( ... e non è detto sia quello che vuoi)

    Nella copia profonda invece crei un altro oggetto identico

    HTH
    ℹ️ Leggi di più su sspintux ...

  7. #7
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Quote Originariamente inviato da SebastianoFloridia Visualizza il messaggio
    E' possibile che il clone funzioni solo per le proprietà principali e su vettore Nodo.Vincoli[6], invece rimane per riferimento.
    Il clone eseguito con il metodo MemberwiseClone() avviene in modo uguale per tutte le proprietà: viene copiato sempre il valore contenuto al loro interno.

    E' chiaro che se parliamo di un float, stiamo parlando di un tipo semplice, nello specifico di un ValueType, quindi il valore viene trasferito da una proprietà all'altra; se si tratta di un array, viene copiato comunque il valore della proprietà, solo che il valore è una reference, ossia un puntatore all'array, perché si tratta di un ReferenceType appunto.

    In breve, tutti i valori vengono copiati, quindi laddove c'è un intero ad esempio, viene copiato un intero, laddove c'è una reference, viene copiato il valore della reference: avrai quindi due copie di un valore che è però un riferimento al medesimo oggetto.

    Proprio per questo ti suggerivo di approfondire la questione, perché vi sono contesti in cui una cosiddetta "shallow copy" va bene, mentre altri in cui si vuole una "deep copy" ossia un clone più profondo (ma dispendioso) dei valori.

    La documentazione in linea di MemberwiseClone comunque è abbastanza esplicita e descrittiva in merito.

    Darei anche un'occhiata al concetto di serializzazione.

    Ciao!
    ℹ️ Leggi di più su _alka_ ...

  8. #8
    Grazie a Tutti!!!
    Sostanzialmente sto progettando un comando UNDO REDO per il mio ambiente grafico.

    Prima di modifica e validare la modifica di un elemento (coordinate di un nodo , colore di una linea, etc..),
    salvo la versione precedente clonando l'oggetto vivo e salvo la successiva versione.
    Mi serve per tornare indietro all'occorrenza.
    Un semplice copia per valore che fotografa un istante ben preciso.
    Grazie Tante

    Sebastiano Floridia

  9. #9
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Quote Originariamente inviato da SebastianoFloridia Visualizza il messaggio
    Sostanzialmente sto progettando un comando UNDO REDO per il mio ambiente grafico.
    Non so se l'approccio che stai adottando sia quello più efficace.

    A livello base, implementando un Command Pattern dovrebbe essere abbastanza semplice implementare le operazioni di "Undo" e "Redo" rovesciando una modifica precedentemente applicata, piuttosto che tenersi una copia dell'intero oggetto prima della modifica.

    Prova a leggere anche questo articolo che potrebbe esserti utile.

    Ciao!
    ℹ️ Leggi di più su _alka_ ...

+ Rispondi al messaggio

Potrebbero interessarti anche ...

  1. Risposte: 3
    Ultimo Post: 10-11-2014, 19:54
  2. duplicare valore record tra tabelle correlate
    Da suppiah69 nel forum Microsoft Access
    Risposte: 2
    Ultimo Post: 11-06-2012, 18:06
  3. Duplicare valore record tra tabelle correlate
    Da suppiah69 nel forum Microsoft Access
    Risposte: 1
    Ultimo Post: 11-06-2012, 11:44
  4. Risposte: 7
    Ultimo Post: 30-07-2010, 15:44
  5. Riferimento a un oggetto SubForm
    Da davideleo nel forum Microsoft Word
    Risposte: 17
    Ultimo Post: 24-06-2006, 13:35