Hoe kloon ik een generieke lijst in C#?

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 newList = new List(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 oldList = new List();
List newList = new List(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 oldList = new List();
List newList = new List(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.

Commentaren (21)

Voor een ondiepe kopie kunt u in plaats daarvan de methode GetRange van de generieke klasse List gebruiken.

List oldList = new List( );
// Populate oldList...

List newList = oldList.GetRange(0, oldList.Count);

Geciteerd uit: Generics Recipes

Commentaren (2)

Als je alleen om waardetypes geeft...

En je kent het type:

List newList = new List(oldList);

Als je het type niet van tevoren weet, heb je een helperfunctie nodig:

List Clone(IEnumerable oldList)
{
    return newList = new List(oldList);
}

De gewoon:

List myNewList = Clone(myOldList);
Commentaren (2)