如何复制List而不影响第一个List

时间:2014-05-12 12:41:41

标签: c# list

我尝试复制列表,但是当我更改第二个列表时,第一个列表会随第二个列表一起更改。

我的模特课:

public class urunler : ICloneable
{
public int id { get; set; }
public string icerik { get; set; }
}

扩展类:

using System.Collections.Generic;
using System;
using System.Linq;

namespace Extensions
{
    public static class Extensions {

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

BLL课程:

using System.Linq;
using Extensions;
public class bll
{
    public void examp
    {
        List<urunler> L1 = new List<urunler>();
        urunler U = new urunler();
        U.icerik="old";
        L1.Add(U);
        List<urunler> L2 = L1.Clone();
        L2[0].icerik="new";
        MessageBox.show(L1[0].icerik);
        MessageBox.show(L2[0].icerik);
        //
    }
}

错误:

error CS0535: `urunler' does not implement interface member `System.ICloneable.Clone()'

然后我尝试更改模型类:

public class urunler : ICloneable
{
    #region ICloneable implementation

    IList<urunler> ICloneable.Clone()
    {
        throw new NotImplementedException ();
    }

    #endregion
    public int id { get; set; }
    public string icerik { get; set; }
}

错误:

error CS0539: `System.ICloneable.Clone' in explicit interface declaration is not a member of interface

这次工作,我改变了我的模型类

public class urunler : ICloneable
{
    public object Clone()         
    {             
        return this.MemberwiseClone();         
    }
    public int id { get; set; }
    public string icerik { get; set; }
}

改变了我的bll类:

//before:
//List<urunler> L2 = L1.Clone();
//after:
List<urunler> L2 = L1.Clone().toList();

5 个答案:

答案 0 :(得分:1)

您没有复制列表,而是在对同一列表进行新的引用。要复制列表,请尝试以下操作:

List<urunler> L2 = new List<urunler>(L1);

答案 1 :(得分:1)

您可以使用ToList()创建副本/新列表

var L2 = L1.ToList();

如果您希望创建新列表,创建单个列表项的副本,则需要在对象定义中添加“克隆”方法:

public class urunler : ICloneable
{
    public Object Clone()
    {
        return this.MemberwiseClone();
    }
}

然后:

var L2 = L1.Select(item => (urunler)item.Clone()).ToList();

答案 2 :(得分:0)

你可以为它编写扩展方法:

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

像这样使用:

List<urunler> L2 = L1.Clone();

你的班级:

public class urunler : ICloneable 
{ 
public int id { get; set; } 
public string ismi { get; set; } 
public string icerik { get; set; }

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

}

答案 3 :(得分:0)

L2 = L1这是错误。 L2引用与L1相同的List。 您需要创建一个新列表并复制项目:

L2 = new List<urunler>();
L1.CopyTo(L1);
//Edit: the above is wrong
L2 = new List<urunler>(L1);

答案 4 :(得分:0)

您的类型urunler似乎是class,因此是引用类型。你能告诉我们urunler课程的定义吗?

因此,即使正确克隆列表,您仍然会生成克隆。两个不同的List<>实例将引用urunler的相同实例。

执行L2 = L1;时,您甚至无法克隆List<>。你只有两个引用相同的List<>,所以在早期就出错了。

当您执行L2 = new List<urunler>(L1);L2 = L1.ToList();L2 = new List<urunler>(); L2.AddRange(L1);时,您会获得我所描述的浅色副本。有两个不同的引用列表,但它们引用相同的urunler实例。

考虑编辑版Dave Bish的答案的克隆解决方案。

根据您的语义,您还可以将urunler设为不可变类型。然后而不是像:

L2[0].icerik = "new";

你必须这样做:

L2[0] = new urunler { icerik = "new", OtherProp = L2[0].OtherProp, };