How do I clone a generic list in C#?

前端 未结 26 2385
失恋的感觉
失恋的感觉 2020-11-22 01:27

I have a generic list of objects in C#, and wish to clone the list. The items within the list are cloneable, but there doesn\'t seem to be an option to do list.Clone()

相关标签:
26条回答
  • 2020-11-22 02:11

    If you only care about value types...

    And you know the type:

    List<int> newList = new List<int>(oldList);
    

    If you don't know the type before, you'll need a helper function:

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

    The just:

    List<string> myNewList = Clone(myOldList);
    
    0 讨论(0)
  • 2020-11-22 02:11

    There is a simple way to clone objects in C# using a JSON serializer and deserializer.

    You can create an extension class:

    using Newtonsoft.Json;
    
    static class typeExtensions
    {
        [Extension()]
        public static T jsonCloneObject<T>(T source)
        {
        string json = JsonConvert.SerializeObject(source);
        return JsonConvert.DeserializeObject<T>(json);
        }
    }
    

    To clone and object:

    obj clonedObj = originalObj.jsonCloneObject;
    
    0 讨论(0)
  • 2020-11-22 02:12

    If your elements are value types, then you can just do:

    List<YourType> newList = new List<YourType>(oldList);
    

    However, if they are reference types and you want a deep copy (assuming your elements properly implement ICloneable), you could do something like this:

    List<ICloneable> oldList = new List<ICloneable>();
    List<ICloneable> newList = new List<ICloneable>(oldList.Count);
    
    oldList.ForEach((item) =>
        {
            newList.Add((ICloneable)item.Clone());
        });
    

    Obviously, replace ICloneable in the above generics and cast with whatever your element type is that implements ICloneable.

    If your element type doesn't support ICloneable but does have a copy-constructor, you could do this instead:

    List<YourType> oldList = new List<YourType>();
    List<YourType> newList = new List<YourType>(oldList.Count);
    
    oldList.ForEach((item)=>
        {
            newList.Add(new YourType(item));
        });
    

    Personally, I would avoid ICloneable because of the need to guarantee a deep copy of all members. Instead, I'd suggest the copy-constructor or a factory method like YourType.CopyFrom(YourType itemToCopy) that returns a new instance of YourType.

    Any of these options could be wrapped by a method (extension or otherwise).

    0 讨论(0)
  • 2020-11-22 02:12

    To clone a list just call .ToList(). This creates a shallow copy.

    Microsoft (R) Roslyn C# Compiler version 2.3.2.62116
    Loading context from 'CSharpInteractive.rsp'.
    Type "#help" for more information.
    > var x = new List<int>() { 3, 4 };
    > var y = x.ToList();
    > x.Add(5)
    > x
    List<int>(3) { 3, 4, 5 }
    > y
    List<int>(2) { 3, 4 }
    > 
    
    0 讨论(0)
  • 2020-11-22 02:13

    Unless you need an actual clone of every single object inside your List<T>, the best way to clone a list is to create a new list with the old list as the collection parameter.

    List<T> myList = ...;
    List<T> cloneOfMyList = new List<T>(myList);
    

    Changes to myList such as insert or remove will not affect cloneOfMyList and vice versa.

    The actual objects the two Lists contain are still the same however.

    0 讨论(0)
  • 2020-11-22 02:15

    If you need a cloned list with the same capacity, you can try this:

    public static List<T> Clone<T>(this List<T> oldList)
    {
        var newList = new List<T>(oldList.Capacity);
        newList.AddRange(oldList);
        return newList;
    }
    
    0 讨论(0)
提交回复
热议问题