J'ai une liste générique d'objets en C#, et je souhaite cloner la liste. Les éléments de la liste peuvent être clonés, mais il ne semble pas y avoir d'option pour faire list.Clone()
.
Existe-t-il un moyen simple de contourner ce problème ?
Si vos éléments sont des types de valeurs, alors vous pouvez simplement faire :
List<YourType> newList = new List<YourType>(oldList);
Cependant, s'il s'agit de types de référence et que vous voulez une copie profonde (en supposant que vos éléments implémentent correctement ICloneable
), vous pouvez faire quelque chose comme ceci :
List<ICloneable> oldList = new List<ICloneable>();
List<ICloneable> newList = new List<ICloneable>(oldList.Count);
oldList.ForEach((item) =>
{
newList.Add((ICloneable)item.Clone());
});
Évidemment, remplacez ICloneable
dans les génériques ci-dessus par le type d'élément qui implémente ICloneable
.
Si votre type d'élément ne supporte pas ICloneable
mais possède un constructeur de copie, vous pouvez faire ceci à la place :
List<YourType> oldList = new List<YourType>();
List<YourType> newList = new List<YourType>(oldList.Count);
oldList.ForEach((item)=>
{
newList.Add(new YourType(item));
});
Personnellement, j'éviterais ICloneable
à cause de la nécessité de garantir une copie profonde de tous les membres. A la place, je suggérerais le constructeur de copie ou une méthode de fabrique comme YourType.CopyFrom(YourType itemToCopy)
qui retourne une nouvelle instance de YourType
.
Chacune de ces options pourrait être enveloppée par une méthode (extension ou autre).
Pour une copie peu profonde, vous pouvez utiliser la méthode GetRange de la classe générique List.
List<int> oldList = new List<int>( );
// Populate oldList...
List<int> newList = oldList.GetRange(0, oldList.Count);
Cité dans : [Generics Recipes][1]
[1] : https://web.archive.org/web/20121230023705/http://en.csharp-online.net/CSharp_Generics_Recipes%E2%80%94Replacing_the_ArrayList_with_Its_Generic_Counterpart "C# Generics Recipes" ;
Si vous ne vous intéressez qu'aux types de valeurs...
Et que vous connaissez le type :
List<int> newList = new List<int>(oldList);
Si vous ne connaissez pas le type avant, vous aurez besoin d'une fonction d'aide :
List<T> Clone<T>(IEnumerable<T> oldList)
{
return newList = new List<T>(oldList);
}
Le juste :
List<string> myNewList = Clone(myOldList);