locked
How to clone the list in c#? RRS feed

  • Question

  • Hi All,

    Can any one please tell the way to clone the List in c# without using the Serialize and Deserialize.?

    Please let me know if you have any concerns.

    Thanks.


    • Edited by Balakumaronline Wednesday, July 4, 2012 3:12 PM Additional changes.
    • Moved by Sheldon _Xiao Friday, July 6, 2012 5:42 AM (From:Windows Presentation Foundation (WPF))
    Wednesday, July 4, 2012 3:09 PM

Answers

  • static class Extensions
    {
    public static IList<T> Clone<T>(this IList<T> list) where T: ICloneable
    {
     return list.Select(i=> (T)i.Clone()).ToList();
    }
    }


    If this post answers your question, please click Mark As Answer. If this post is helpful please click Mark as Helpful.

    Regards,
    Nairs

    Wednesday, July 4, 2012 3:41 PM
  • Hi,

    as you want a cloned list, you can use one of the standard constructors like this:

    List<Person> persons = new List<Person> {
       new Person{Name="AYoungOne", Age=1},
       new Person{Name="AnOldOne", Age=100}};
    
    List<Person> clones = new List<Person>(persons);

    This way you get a new list with the same references (if you have a list of classes) as the original. That means when you change persons[0].Name the change is reflected in clones[0].Name.

    If you don't want that (i. e. you want full copies), you can use the suggestion from Nair S where you can copy classes that implement ICloneable. Or you use LINQ like this:

    List<Person> persons = new List<Person> {
    new Person{Name="AYoungOne", Age=1}, new Person{Name="AnOldOne", Age=100}}; List<Person> copies = (from person in persons select new Person { Name = person.Name, Age = person.Age }).ToList();

    Here we generate completely new 'Persons' and a change to pesons[0].Name does not change copies[0].Name. The construction of the copies (in both ways: with LINQ or ICloneable) is subject to the complexity of your class (where I used Person).

    Cheers
    Jürgen

    Wednesday, July 4, 2012 5:22 PM
  • Hi Bala

    Jurgen is right to use that u need to impliement IClonable interface to your class like

    implement Iclonable interface to the class like this 

    public class Person :INotifyPropertyChanged,ICloneable

    {

     object ICloneable.Clone()
            {
                return this.Clone();
            }

     public Person Clone()
            {
                return (Person)this.MemberwiseClone();
            }

    public int Id { get; set; }

    public string Name { get; set; }

    public string LastName { get; set; }

    }

    Hope it will help you.... let me know... :)

    Have a nice day....


    Harshad..... Always 4 U

    Friday, July 6, 2012 5:19 AM
  • I have included a code block on how the give solution for List Clone can be applied

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace WindowsFormsApplication1
    {
        public class ListClone
        {
            public ListClone()
            {
                SomeMethod();
            }
    
            public void SomeMethod()
            {
                //Here I am using String as input value type. You can supply any type irrespetive of built-in or custom
                List<string> listB = new List<string>();
                listB.AddRange(new[] { "Four", "Five", "Six" });
    
                IList<string> clonedList = listB.Clone<string>();
            }
        }
        static class Extensions
        {
            public static IList<T> Clone<T>(this IList<T> list) where T : ICloneable
            {
                return list.Select(i => (T)i.Clone()).ToList();
            }
        }
    }

    Update me for more detail.


    If this post answers your question, please click Mark As Answer. If this post is helpful please click Mark as Helpful.

    Regards,
    Nairs

    Tuesday, July 10, 2012 9:26 PM

All replies

  • static class Extensions
    {
    public static IList<T> Clone<T>(this IList<T> list) where T: ICloneable
    {
     return list.Select(i=> (T)i.Clone()).ToList();
    }
    }


    If this post answers your question, please click Mark As Answer. If this post is helpful please click Mark as Helpful.

    Regards,
    Nairs

    Wednesday, July 4, 2012 3:41 PM
  • Hi,

    Can you please tell how to use this extension in application.

    Thanks.

    Wednesday, July 4, 2012 4:03 PM
  • Hi,

    as you want a cloned list, you can use one of the standard constructors like this:

    List<Person> persons = new List<Person> {
       new Person{Name="AYoungOne", Age=1},
       new Person{Name="AnOldOne", Age=100}};
    
    List<Person> clones = new List<Person>(persons);

    This way you get a new list with the same references (if you have a list of classes) as the original. That means when you change persons[0].Name the change is reflected in clones[0].Name.

    If you don't want that (i. e. you want full copies), you can use the suggestion from Nair S where you can copy classes that implement ICloneable. Or you use LINQ like this:

    List<Person> persons = new List<Person> {
    new Person{Name="AYoungOne", Age=1}, new Person{Name="AnOldOne", Age=100}}; List<Person> copies = (from person in persons select new Person { Name = person.Name, Age = person.Age }).ToList();

    Here we generate completely new 'Persons' and a change to pesons[0].Name does not change copies[0].Name. The construction of the copies (in both ways: with LINQ or ICloneable) is subject to the complexity of your class (where I used Person).

    Cheers
    Jürgen

    Wednesday, July 4, 2012 5:22 PM
  • Hi Bala

    you may also try for this

    List<MyType> lstCloned = lstOriginal.Select(i => i.Clone()).ToList();


    Harshad..... Always 4 U

    Thursday, July 5, 2012 5:51 AM
  • Hi Harshad,

    I got this error when using the above code. The exception is "does not contain a definition for 'Clone' and no extension method 'Clone'". Can you please tell how to implement the Clone method?

    Thanks.

    Thursday, July 5, 2012 6:07 PM
  • Hi,

    as I already said: the suggestion from Nair S and from harjohn (which are equal) require, that the class of the elements in your list implements the ICloneable interface. If it does not, you can't use them. Or you have to write an extension method named "Clone" for your class (both is true for every class which can be contained in a list-to-clone).

    Why don't you want to use the standard constructor? It is by far the most simple solution in this thread.

    Cheers
    Jürgen

    Thursday, July 5, 2012 7:11 PM
  • Hi Bala

    Jurgen is right to use that u need to impliement IClonable interface to your class like

    implement Iclonable interface to the class like this 

    public class Person :INotifyPropertyChanged,ICloneable

    {

     object ICloneable.Clone()
            {
                return this.Clone();
            }

     public Person Clone()
            {
                return (Person)this.MemberwiseClone();
            }

    public int Id { get; set; }

    public string Name { get; set; }

    public string LastName { get; set; }

    }

    Hope it will help you.... let me know... :)

    Have a nice day....


    Harshad..... Always 4 U

    Friday, July 6, 2012 5:19 AM
  • I have included a code block on how the give solution for List Clone can be applied

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace WindowsFormsApplication1
    {
        public class ListClone
        {
            public ListClone()
            {
                SomeMethod();
            }
    
            public void SomeMethod()
            {
                //Here I am using String as input value type. You can supply any type irrespetive of built-in or custom
                List<string> listB = new List<string>();
                listB.AddRange(new[] { "Four", "Five", "Six" });
    
                IList<string> clonedList = listB.Clone<string>();
            }
        }
        static class Extensions
        {
            public static IList<T> Clone<T>(this IList<T> list) where T : ICloneable
            {
                return list.Select(i => (T)i.Clone()).ToList();
            }
        }
    }

    Update me for more detail.


    If this post answers your question, please click Mark As Answer. If this post is helpful please click Mark as Helpful.

    Regards,
    Nairs

    Tuesday, July 10, 2012 9:26 PM
  • Hi Nair,

    Yes this is works fine when i use the built-in type. But when i use the custom type it shows the error in the line  "listB.Clone<B>()" like this,

    The type '............B' cannot be used as type parameter 'T' in the generic type or method '.........Extensions.Clone<T>(System.Collections.Generic.IList<T>)'. There is no implicit reference conversion from '........B' to 'System.ICloneable'. 

    The code is:

    -----------------------

    public class A:List<B>,ICloneable

    {

                   public object Clone()

                   {

                                   List<B> listB = new List<B>();

                                   listB.AddRange(this);

                                   IList<B> clonedList = listB.Clone<B>();

                                   return clonedList;

                   }

    }

    static class Extensions

    {

         public static IList<T> Clone<T>(this IList<T> list) where T : ICloneable

            {

                return list.Select(i => (T)i.Clone()).ToList();

            }

        }

     public class B

        {

    ................

    ................

         }

    Please help me on this.

    Thanks.

    
    

    Tuesday, July 17, 2012 9:48 AM