2015-10-16 112 views
1

我想将list1中的项目列表复制到另一个列表list2。我能够做到这一点。不过,我不希望list2中所做的更改反映在list1中。将项目列表复制到另一个列表

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<MyClass> list1 = new List<MyClass>(); 
     list1.Add(new MyClass(){ID = 1, Name = "name1"}); 
     list1.Add(new MyClass(){ID = 2, Name = "name2"}); 
     list1.Add(new MyClass(){ID = 3, Name = "name3"}); 

     //Copy items from list1 to list2 
     List<MyClass> list2 = new List<MyClass>(list1); 

     list1.ForEach(x => Console.WriteLine(x.Name)); //It shows the name as added 

     //Empty items in list2 
     list2.ForEach(x => x.Name = string.Empty); 

     //Print items in list1 
     list1.ForEach(x => Console.WriteLine(x.Name)); //It shows the name is empty 
     Console.ReadKey(); 
    } 
} 

class MyClass 
{ 
    private int id; 

    public int ID 
    { 
     get { return id; } 
     set { id = value; } 
    } 

    private string name; 

    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 
} 

我希望应该有一个简单的方法。

+0

你需要的只是一个深层复制。尝试自己做。 –

回答

3

由于这是您要更改所有引用类型。你需要创建一个实例的副本

public class MyClass 
{ 
    private int id; 

    public int ID 
    { 
     get { return id; } 
     set { id = value; } 
    } 

    private string name; 

    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 

    public MyClass Copy() 
    { 
     return new MyClass 
     { 
      ID = this.ID, 
      Name = this.Name 
     }; 
    } 
} 

现在你可以通过这种方式创建第二个列表:

List<MyClass> list2 = new List<MyClass>(list1.Select(x => x.Copy())); 

当然你不需要这个方法。你可以做到这一点也即时在LINQ查询:

List<MyClass> list2 = new List<MyClass>(list1.Select(x => new MyClass { ID = x.ID, Name = x.Name })); 

另一个类似的方法是copy-constructor。拷贝构造函数是用来初始化实例提供相同类型的另一个实例:

public class MyClass 
{ 
    private int id; 

    public MyClass(MyClass instance) 
    { 
     this.id = instance.ID; 
     this.name = instance.Name; 
    } 

    public int ID 
    { 
     get { return id; } 
     set { id = value; } 
    } 

    private string name; 

    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 
} 

现在你可以填补这样的副本列表:

List<MyClass> list2 = new List<MyClass>(list1.Select(x => new MyClass(x))); 

List.ConvertAll

List<MyClass> list2 = list1.ConvertAll(x => new MyClass(x)); 
+0

谢谢@Tim。 。它为我工作。我希望这是复制构造函数。不确定:) – Gopichandar

+0

@Gopichandar:什么是_copy constructor_?不过,我很高兴它帮助你。 –

+1

@Gopichandar:它不是一个复制构造器,因为它不是一个构造函数,而是一个普通的实例方法。它类似于工厂方法。复制构造函数用于通过提供另一个相同类型的实例来初始化实例。你也可以这样做。这是一个相似但不同的方法。 –

1

如果你想使用在其他地方这个功能太,我想做到最好的办法是,为IList这样创建的一个推广方法:

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

,并使用它,你应该改变你的类并使其ICloneable

class MyList : ICloneable 
{ 
    public MyList(int idParam, string nameParam) 
    { 
     ID = idParam; 
     Name = nameParam; 
    } 
    public object Clone() 
    { 
     return new MyList(ID, Name); 
    } 

    private int id; 
    public int ID 
    { 
     get { return id; } 
     set { id = value; } 
    } 

    private string name; 
    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 
} 
+0

[为什么没有ICloneable ?](http://stackoverflow.com/questions/536349/why-no-icloneablet)... [我们应该过时ICloneable](http://blogs.msdn.com/b/brada /archive/2004/05/03/125427.aspx) –

-1

你可以试试这个:

List<MyList> list2=list1.ToList(); 

我希望这有助于

+0

我的直觉说它不会工作。让我试试这个。 – Gopichandar

+0

这这么想的工作,所以你可以使用这个 名单列表2 =新名单(); 从列表1 //复制项列表2 的foreach(List1中VAR myList中) { MyClass的项=新MyClass的() { ID = myList.ID, 名称= myList.Name }; list2.Add(item); } – dino

1

如果你的元素是引用类型和类型实现ICloneable界面,你clould做这样的事情:

list1.ForEach((item) => 
{ 
    list2.Add((ICloneable)item.Clone()); 
}); 

如果你的元素类型不实现ICloneable,你clould创建“复制”的构造和做这样的事情:

list1.ForEach((item)=> 
    { 
     list2.Add(new MyList(item.ID, item.Name)); 
    }); 
+1

'IClonable'合约没有指定所执行的克隆的类型,不同的类具有不同的实现。消费者不能依赖ICloneable来让他们知道对象是否被深度克隆。为此,应该避免。 –

相关问题