Principale utente con più risposte
Copiare una Lista di oggetti elemento per elemento, e non solo l'indirizzo

Domanda
-
Salve a tutti.
Ne aprofitto per ringraziare gli utenti di questo forum, sempre pronti a rispondere velocemente alle domande!
Dunque, mi chiedevo come è possibile copiare una lista di oggetti in una nuova lista elemento per elemento.Mi spiego meglio:
ho una lista di oggetti List<object> x = new List<object> ();
se io faccio List <object> y = x; viene passato il riferimento all'oggetto x, dunque viene copiato l'indirizzo.
Ma se io voglio copiare in y tutto gli oggetti della lista di x, devo per forza fare questo
foreach (object z in x) { y.Add(z); }
E' possibile che non abbiano previsto un metodo per questo tipo di operazione??
Nella pagina della Guida in linea di Microsoft non c'è un metodo che fa ciò che voglio......
Non esiste un'altra strada se non utilizzare un foreach??
grazie a tutti
Risposte
-
Salve a tutti.
Ne aprofitto per ringraziare gli utenti di questo forum, sempre pronti a rispondere velocemente alle domande!
Dunque, mi chiedevo come è possibile copiare una lista di oggetti in una nuova lista elemento per elemento.Mi spiego meglio:
ho una lista di oggetti List<object> x = new List<object> ();
se io faccio List <object> y = x; viene passato il riferimento all'oggetto x, dunque viene copiato l'indirizzo.
Ma se io voglio copiare in y tutto gli oggetti della lista di x, devo per forza fare questo
foreach (object z in x) { y.Add(z); }
E' possibile che non abbiano previsto un metodo per questo tipo di operazione??
Nella pagina della Guida in linea di Microsoft non c'è un metodo che fa ciò che voglio......
Non esiste un'altra strada se non utilizzare un foreach??
grazie a tuttiValuta queste soluzioni:
http://stackoverflow.com/questions/222598/how-do-i-clone-a-generic-list-in-c
http://stackoverflow.com/questions/9622211/how-to-make-correct-clone-of-the-listmyobject
- Proposto come risposta Irina Turcu lunedì 10 febbraio 2014 13:32
- Contrassegnato come risposta Irina Turcu lunedì 17 febbraio 2014 16:54
-
Ciao,
potresti fare così :
public class CloneableList<T> : List<T>, ICloneable { public virtual object Clone() { var result = (CloneableList<T>)Activator.CreateInstance(this.GetType()); this.ForEach(f => { Type t = f.GetType(); var obj = (T)Activator.CreateInstance(t);
//seleziona con BindingFlags nei parametri di getProperties() il tipo di proprietà da clonare t.GetProperties().ToList().ForEach(p => { p.SetValue(obj, p.GetValue(f, null), null); }); result.Add(obj); }); return result; } }
In pratica non faccio altro che usare la reflection per recuperare il tipo usato che sta nella lista, ne ricavo le proprietà (occhio che qui dovrai sceglierle bene con i BindingFlags, non necessariamente tutte vanno impostate, ad esempio le private no), e le imposto al nuovo oggetto creato. Alla fine restituisco la lista creata dinamicamente.
la usi così :
var tt = new Entità1(); tt.Myproperty = "qualcosa"; var t = new Entità1(); t.Myproperty = "altro"; var lista = new CloneableList<object>(); lista.Add(t); lista.Add(tt); var lista2 = lista.Clone();
t.Myproperty = "Cambiato";//cambia solo in lista, non in lista2
Comunque secondo me è preferibile che gli elementi di tipo T siano ICloneable, ma dovresti implementare l'interfaccia in tutti i tipi che intendi usare nella lista. In questo caso allora ti basta iterare gli insiemi e chiamare Clone su di loro. Diversamente lo cloni come ti ho mostrato.
- Modificato U 235 giovedì 6 febbraio 2014 04:32
- Proposto come risposta Irina Turcu lunedì 10 febbraio 2014 13:32
- Contrassegnato come risposta Irina Turcu lunedì 17 febbraio 2014 16:55
-
Se i tuoi oggetti sono serializzabili puoi anche crearne delle "copie" serializzando e deserializzandoli :
public static T DeepClone<T>(T obj) { T objResult; using (MemoryStream ms = new MemoryStream()) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, obj); ms.Position = 0; objResult = (T)bf.Deserialize(ms); } return objResult; }
Quindi puoi creare le tue istanze "clone" dei tuoi oggetti in questo modo :
MyClass copy = obj.DeepClone();
Saluti.
- Proposto come risposta Irina Turcu lunedì 10 febbraio 2014 13:32
- Contrassegnato come risposta Irina Turcu lunedì 17 febbraio 2014 16:54
Tutte le risposte
-
-
Salve a tutti.
Ne aprofitto per ringraziare gli utenti di questo forum, sempre pronti a rispondere velocemente alle domande!
Dunque, mi chiedevo come è possibile copiare una lista di oggetti in una nuova lista elemento per elemento.Mi spiego meglio:
ho una lista di oggetti List<object> x = new List<object> ();
se io faccio List <object> y = x; viene passato il riferimento all'oggetto x, dunque viene copiato l'indirizzo.
Ma se io voglio copiare in y tutto gli oggetti della lista di x, devo per forza fare questo
foreach (object z in x) { y.Add(z); }
E' possibile che non abbiano previsto un metodo per questo tipo di operazione??
Nella pagina della Guida in linea di Microsoft non c'è un metodo che fa ciò che voglio......
Non esiste un'altra strada se non utilizzare un foreach??
grazie a tuttiValuta queste soluzioni:
http://stackoverflow.com/questions/222598/how-do-i-clone-a-generic-list-in-c
http://stackoverflow.com/questions/9622211/how-to-make-correct-clone-of-the-listmyobject
- Proposto come risposta Irina Turcu lunedì 10 febbraio 2014 13:32
- Contrassegnato come risposta Irina Turcu lunedì 17 febbraio 2014 16:54
-
Ciao,
potresti fare così :
public class CloneableList<T> : List<T>, ICloneable { public virtual object Clone() { var result = (CloneableList<T>)Activator.CreateInstance(this.GetType()); this.ForEach(f => { Type t = f.GetType(); var obj = (T)Activator.CreateInstance(t);
//seleziona con BindingFlags nei parametri di getProperties() il tipo di proprietà da clonare t.GetProperties().ToList().ForEach(p => { p.SetValue(obj, p.GetValue(f, null), null); }); result.Add(obj); }); return result; } }
In pratica non faccio altro che usare la reflection per recuperare il tipo usato che sta nella lista, ne ricavo le proprietà (occhio che qui dovrai sceglierle bene con i BindingFlags, non necessariamente tutte vanno impostate, ad esempio le private no), e le imposto al nuovo oggetto creato. Alla fine restituisco la lista creata dinamicamente.
la usi così :
var tt = new Entità1(); tt.Myproperty = "qualcosa"; var t = new Entità1(); t.Myproperty = "altro"; var lista = new CloneableList<object>(); lista.Add(t); lista.Add(tt); var lista2 = lista.Clone();
t.Myproperty = "Cambiato";//cambia solo in lista, non in lista2
Comunque secondo me è preferibile che gli elementi di tipo T siano ICloneable, ma dovresti implementare l'interfaccia in tutti i tipi che intendi usare nella lista. In questo caso allora ti basta iterare gli insiemi e chiamare Clone su di loro. Diversamente lo cloni come ti ho mostrato.
- Modificato U 235 giovedì 6 febbraio 2014 04:32
- Proposto come risposta Irina Turcu lunedì 10 febbraio 2014 13:32
- Contrassegnato come risposta Irina Turcu lunedì 17 febbraio 2014 16:55
-
Se i tuoi oggetti sono serializzabili puoi anche crearne delle "copie" serializzando e deserializzandoli :
public static T DeepClone<T>(T obj) { T objResult; using (MemoryStream ms = new MemoryStream()) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, obj); ms.Position = 0; objResult = (T)bf.Deserialize(ms); } return objResult; }
Quindi puoi creare le tue istanze "clone" dei tuoi oggetti in questo modo :
MyClass copy = obj.DeepClone();
Saluti.
- Proposto come risposta Irina Turcu lunedì 10 febbraio 2014 13:32
- Contrassegnato come risposta Irina Turcu lunedì 17 febbraio 2014 16:54