Jeg har en generisk liste af objekter i C# og ønsker at klone listen. Elementerne i listen kan klones, men der synes ikke at være en mulighed for at udføre list.Clone()
.
Er der en nem måde at omgå dette på?
Hvis dine elementer er værdityper, kan du bare gøre det:
List<YourType> newList = new List<YourType>(oldList);
Men hvis de er referencetyper, og du vil have en dyb kopi (forudsat at dine elementer implementerer ICloneable
korrekt), kan du gøre noget i stil med dette:
List<ICloneable> oldList = new List<ICloneable>();
List<ICloneable> newList = new List<ICloneable>(oldList.Count);
oldList.ForEach((item) =>
{
newList.Add((ICloneable)item.Clone());
});
Du skal naturligvis erstatte ICloneable
i ovenstående generics og caste med hvad end din elementtype er, der implementerer ICloneable
.
Hvis din elementtype ikke understøtter ICloneable
, men har en copy-constructor, kan du gøre dette i stedet:
List<YourType> oldList = new List<YourType>();
List<YourType> newList = new List<YourType>(oldList.Count);
oldList.ForEach((item)=>
{
newList.Add(new YourType(item));
});
Personligt ville jeg undgå ICloneable
på grund af behovet for at garantere en dyb kopi af alle medlemmer. I stedet ville jeg foreslå copy-constructor eller en fabriksmetode som YourType.CopyFrom(YourType itemToCopy)
, der returnerer en ny instans af YourType
.
Enhver af disse muligheder kunne indpakkes af en metode (udvidelse eller andet).
Hvis du vil have en overfladisk kopi, kan du i stedet bruge GetRange-metoden i den generiske List-klasse.
List<int> oldList = new List<int>( );
// Populate oldList...
List<int> newList = oldList.GetRange(0, oldList.Count);
Citeret fra: Generics Recipes
Hvis du kun interesserer dig for værdityper...
Og du kender typen:
List<int> newList = new List<int>(oldList);
Hvis du ikke kender typen i forvejen, skal du bruge en hjælpefunktion:
List<T> Clone<T>(IEnumerable<T> oldList)
{
return newList = new List<T>(oldList);
}
Den bare:
List<string> myNewList = Clone(myOldList);