Ik heb een generieke lijst van objecten in C#, en ik wil de lijst klonen. De items in de lijst zijn kloonbaar, maar er lijkt geen optie te zijn om list.Clone()
te doen.
Is er een makkelijke manier om dit te omzeilen?
Als je elementen waarde types zijn, dan kun je gewoon doen:
List<YourType> newList = new List<YourType>(oldList);
Als het echter referentietypes zijn en je wilt een diepe kopie (ervan uitgaande dat je elementen ICloneable
goed implementeren), dan zou je iets als dit kunnen doen:
List<ICloneable> oldList = new List<ICloneable>();
List<ICloneable> newList = new List<ICloneable>(oldList.Count);
oldList.ForEach((item) =>
{
newList.Add((ICloneable)item.Clone());
});
Vervang uiteraard ICloneable
in de bovenstaande generics en cast met wat voor elementtype dan ook dat ICloneable
implementeert.
Als je element type ICloneable
niet ondersteunt, maar wel een copy-constructor heeft, zou je dit in plaats daarvan kunnen doen:
List<YourType> oldList = new List<YourType>();
List<YourType> newList = new List<YourType>(oldList.Count);
oldList.ForEach((item)=>
{
newList.Add(new YourType(item));
});
Persoonlijk zou ik ICloneable
vermijden vanwege de noodzaak om een diepe kopie van alle leden te garanderen. In plaats daarvan zou ik de copy-constructor voorstellen of een factory method zoals YourType.CopyFrom(YourType itemToCopy)
die een nieuwe instantie van YourType
teruggeeft.
Elk van deze opties kan door een methode (extensie of anderszins) worden omhuld.
Voor een ondiepe kopie kunt u in plaats daarvan de methode GetRange van de generieke klasse List gebruiken.
List<int> oldList = new List<int>( );
// Populate oldList...
List<int> newList = oldList.GetRange(0, oldList.Count);
Geciteerd uit: Generics Recipes
Als je alleen om waardetypes geeft...
En je kent het type:
List<int> newList = new List<int>(oldList);
Als je het type niet van tevoren weet, heb je een helperfunctie nodig:
List<T> Clone<T>(IEnumerable<T> oldList)
{
return newList = new List<T>(oldList);
}
De gewoon:
List<string> myNewList = Clone(myOldList);