Comment créer une nouvelle copie (clone) d'une Liste<T>?
Dans le morceau de code suivant,
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace clone_test_01
{
public partial class MainForm : Form
{
public class Book
{
public string title = "";
public Book(string title)
{
this.title = title;
}
}
public MainForm()
{
InitializeComponent();
List<Book> books_1 = new List<Book>();
books_1.Add( new Book("One") );
books_1.Add( new Book("Two") );
books_1.Add( new Book("Three") );
books_1.Add( new Book("Four") );
List<Book> books_2 = new List<Book>(books_1);
books_2[0].title = "Five";
books_2[1].title = "Six";
textBox1.Text = books_1[0].title;
textBox2.Text = books_1[1].title;
}
}
}
- Je utiliser un Book
type d'objet à créer un List<T>
et je le remplir avec quelques éléments en leur donnant un titre unique (à partir de 'un' à 'cinq').
Puis-je créer List<Book> books_2 = new List<Book>(books_1)
.
À partir de ce point, je sais que c'est un clone de l'objet de la liste, MAIS le livre des objets à partir de book_2
sont toujours une référence dans le livre des objets dans books_1
. C'est prouvé par faire des modifications sur les deux premiers éléments de books_2
, puis de la vérification de ces mêmes éléments de book_1
dans un TextBox
.
books_1[0].title and books_2[1].title
ont en effet été modifiés pour les nouvelles valeurs de books_2[0].title and books_2[1].title
.
MAINTENANT, LA QUESTION
Comment pouvons-nous créer une nouvelle copie papier d'une List<T>
? L'idée est que books_1
et books_2
devenir complètement indépendants les uns des autres.
Je suis déçu, Microsoft n'a pas d'offrir un cadre soigné, une solution rapide et simple comme le Rubis sont faites avec le clone()
méthode.
Ce serait vraiment génial d'aides est d'utiliser mon code et le modifier avec une solution réalisable de sorte qu'il peut être compilé et le travail. Je pense qu'il va vraiment aider les débutants d'essayer de comprendre les solutions proposées pour ce problème.
EDIT: Notez que le Book
classe pourrait être plus complexes et ont plus de propriétés. J'ai essayé de garder les choses simples.
- Quelque chose comme
CopyTo
? - Ce type de copie est normalement appelé copie. Si vous vous sentez "hard copy" est quelque chose de différent que vous avez réellement besoin dans votre cas, veuillez annuler ma modifier et ajouter votre définition du terme.
- papier signifie que vous imprimez sur une feuille de papier physique.
- S'il vous plaît consulter d'autres liées à des questions à propos de deep-copie demandé avant - stackoverflow.com/questions/tagged/...
- Je voulais dire de copie en profondeur, en effet, désolé, je suis encore débutants.
- Personnellement, j'aime utiliser une sérialisation & deserialisation routine qui réalise la copie en profondeur - de/sérialisation est lente(ish), mais cela fonctionne n'importe comment beaucoup de propriétés de l'objet. Malheureusement, je suis en vacances, donc je ne peux pas poster le code.
- Copie en profondeur chaque élément de la liste. Il dépend du contenu de votre liste.
- OMI profonde clonage est intrinsèquement pas soigné.
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin pour créer de nouveaux
Book
les objets, puis de les placer dans un nouveauList
:Mise à jour: un peu plus simple...
List<T>
a une méthode appeléeConvertAll
qui retourne une nouvelle liste:ToList()
pas assez? Pourquoi avez-vous besoinSelect
déclaration de trop?ToList()
seul serait une copie superficielle. LeSelect
copie non seulement la liste, mais les objets à l'intérieur.Créer un générique
ICloneable<T>
interface dont vous mettez en œuvre dans votreBook
classe de sorte que la classe sait comment créer une copie de lui-même.Vous pouvez alors utiliser linq ou
ConvertAll
méthodes que Marque est mentionnée.ou
Sauf que ne pas créer une copie en profondeur, il crée une copie superficielle.
Avec une profonde copie, vous devez toujours être prudent, exactement ce que vous souhaitez copier. Quelques exemples de questions possibles sont:
Book
a unAuthor
etAuthor
a une liste de sesBook
s.Stream
qui écrit dans un fichier.Window
.Maintenant, il y a fondamentalement deux manières de procéder pour clone quelque chose:
Clone()
méthode dans chaque classe que vous avez besoin cloné. (Il est égalementICloneable
interface, mais vous devriez pas l'utiliser; à l'aide d'un customICloneable<T>
interface comme Trevor proposé est d'accord.) Si vous savez que tous vous avez besoin est de créer une copie de chaque champ de cette classe, vous pouvez utiliserMemberwiseClone()
à mettre en œuvre. Comme alternative, vous pouvez créer un “constructeur de copie”:public Book(Book original)
.MemoryStream
et puis désérialiser de retour. Cela vous oblige à marquer chaque classe comme[Serializable]
et il peut également être configuré exactement quoi (et comment) devrait être sérialisé. Mais ce n'est plus un “rapide et sale” solution, et sera probablement moins performant.Qui devrait faire exactement ce que vous voulez. Montré ici.
Bien,
Si vous cochez toutes les personnes impliquées classes sérialisables, vous pouvez :
Source:
https://social.msdn.microsoft.com/Forums/en-US/5c9b4c31-850d-41c4-8ea3-fae734b348c4/copy-listsomeobject-to-clone-list?forum=csharpgeneral
Depuis
Clone
serait de retourner une instance de l'objet du Livre, cet objet devrait d'abord être converti dans un Livre avant que vous pouvez appelerToList
sur elle. L'exemple ci-dessus doit être écrit:Si le Tableau de la classe répond à vos besoins, vous pouvez également utiliser la Liste.ToArray méthode, qui copie les éléments d'un tableau.
Référence: http://msdn.microsoft.com/en-us/library/x303t819(v=vs. 110).aspx
Vous pouvez utiliser ceci: