80

例如

List<string> name_list1 = new List<string>();
List<string> name_list2 = new List<string>();

稍后在代码中:

name_list1.Add("McDonald");
name_list1.Add("Harveys");
name_list1.Add("Wendys");

name_list2 = name_list1; // I make a copy of namelist1 to namelist2

因此,从这一点开始,我想继续在 name_list2 中添加元素或进行更改,而不影响 name_list1。我怎么做?

4

14 回答 14

175
name_list2 = new List<string>(name_list1);

这将克隆列表。

编辑:此解决方案仅适用于原始类型。对于对象,请参阅下面的其他回复。

于 2012-11-19T03:29:10.337 回答
11

另一种选择是:深度克隆

public static T DeepCopy<T>(T item)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            formatter.Serialize(stream, item);
            stream.Seek(0, SeekOrigin.Begin);
            T result = (T)formatter.Deserialize(stream);
            stream.Close();
            return result;
        }

所以,

您可以使用 :

name_list2 = DeepCopy<List<string>>(name_list1);

或者:

name_list2 = DeepCopy(name_list1); 

也将工作。

于 2016-02-23T07:51:31.117 回答
7

对于原始类型,您可以这样做:

List<string> CopyList = new List<string>(OriginalList);

对于非原始/用户定义的类型,您可以这样做:

List<Person> CopyList = new List<Person>();
foreach(var item in OriginalList)
{
    CopyList.Add(new Person { 
            Name = item.Name,
            Address = item.Address
    });
}
于 2018-10-03T11:21:04.333 回答
5
name_list2 = new List<string>(name_list1); // Clone list into a different object

此时,两个列表是不同的对象。您可以在不影响 list1 的情况下将项目添加到 list2

于 2012-11-19T03:30:00.880 回答
4

问题是任务。在赋值之前,变量和name_list2 = name_list1;指向的堆上有两个不同的 List 对象。你填满,这很好。但作业说,“将堆上的同一个对象指向.” 曾经指向的 List不再可访问,将被垃圾回收。你真正想要的是将内容复制到. 您可以使用List.AddRange执行此操作。请注意,这将导致“浅”副本,这对于您引用的示例很好,其中列表内容是字符串,但当列表成员是更复杂的对象时可能不是您想要的。这一切都取决于您的需求。name_list1name_list2name_list1name_list2name_list1name_list2name_list1name_list2

于 2012-11-19T03:34:34.507 回答
3

我更喜欢 Json 转换器的方法来序列化和反序列化,这样你就不必标记要序列化的类,尤其是你有很多子类。

https://www.newtonsoft.com/json/help/html/SerializingJSON.htm

于 2018-01-17T06:07:31.763 回答
2

这是一个替代解决方案:

    List<string> name_list1 = new List<string>();
    List<string> name_list2 = new List<string>();

    name_list1.Add("McDonald");
    name_list1.Add("Harveys");
    name_list1.Add("Wendys");

    name_list2.AddRange(name_list1.ToArray());

ToArray() 方法将“name_list1”复制到一个新数组,然后我们通过 AddRange() 方法将其添加到 name_list2。

于 2016-04-01T17:34:31.290 回答
2

我喜欢 linq 这...

如果列表元素是基元或结构,那么......

L2 = L1.ToList()

如果列表元素是类,那么...

L2 = L1.Select(x => x.Copy()).ToList();

哪里Copy可能只是浅拷贝曝光MemberWiseClone,也可能是深度拷贝的某种实现。

于 2017-01-27T18:47:04.753 回答
1

对于原始类型:
List ClonedList = new list(OriginalList);

对于非原始/用户定义类型:
我们需要进行深拷贝:深拷贝用于对内部引用类型进行完整的深拷贝,为此我们需要配置 MemberwiseClone() 返回的对象。

Step1- 在你的类中从 ICloneable 继承:
public class MyClass:ICloneable

Step2- 实现方法

public MyClass Clone()
{
  MyClass MyClassObj =new MyClass();
  MyClassObj.Property1 = this.Property1;
  .
  .
  MyClassObj.Property_N = this.Property_N;
  return MyClass;
}

Step3- 现在克隆你的列表

List<MyClass> MyClassClone = new List<MyClass>(); 
for(i=0; i<Count; i++)
  {
      MyClassClone.Add(OriginalClaaObj[i].Clone());
  }

这将对对象的每个项目进行深层复制。

于 2018-04-25T16:17:28.327 回答
0

使用类对象列表时,上述解决方案都不适合我。

这可用于将任何对象复制到具有共享属性名称的另一个对象。

public static void ObjectToObject(object source, object destination)
{
  // Purpose : Use reflection to set property values of objects that share the same property names.
  Type s = source.GetType();
  Type d = destination.GetType();

  const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;

  var objSourceProperties = s.GetProperties(flags);
  var objDestinationProperties = d.GetProperties(flags);

  var propertyNames = objSourceProperties
  .Select(c => c.Name)
  .ToList();

  foreach (var properties in objDestinationProperties.Where(properties => propertyNames.Contains(properties.Name)))
  {

    try
    {
      PropertyInfo piSource = source.GetType().GetProperty(properties.Name);

      properties.SetValue(destination, piSource.GetValue(source, null), null);
    }
    catch (Exception ex)
    {
      throw;
    }

  }
}


public static List<T> CopyList<T>(this List<T> lst)
{
  List<T> lstCopy = new List<T>();

  foreach (var item in lst)
  {
    var instanceOfT = Activator.CreateInstance<T>();
    ObjectToObject(item, instanceOfT);
    lstCopy.Add(instanceOfT);
  }
  return lstCopy;
}

对于列表,请使用:list2 = list1.CopyList();

于 2018-09-27T15:08:03.957 回答
0

如果两个列表都属于相同的复杂类型,那么您可以执行以下操作:-

SomeClass List2 = new List();

List1.ForEach(u => List2.Add(u));

我正在做的是循环遍历 List1 的每个元素并继续将其添加到 List2 中。我相信这是最短的方法。

于 2019-02-19T11:12:05.190 回答
0

虽然它可能是潜在的性能威胁解决方案,但它会雄辩地逐个属性地复制值。

using Newstonsoft.Json;

ClassA classA = new ClassA();
ClassA classACopyWithoutReference = JsonConvert.DeserializeObject<ClassA>(JsonConvert.SerializeObject(classA));
于 2020-06-08T09:28:02.917 回答
0

基于@Mrunal 的回答,我创建了一个扩展方法:

public static T Clone<T>(this T source)
    {
        // Don't serialize a null object, simply return the default for that object
        if (source == null)
        {
            return default;
        }

        // initialize inner objects individually
        // for example in default constructor some list property initialized with some values,
        // but in 'source' these items are cleaned -
        // without ObjectCreationHandling.Replace default constructor values will be added to result
        var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace };

        return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings);
    }

你可以这样称呼它:

L2 = L1.Select(x => x.Clone()).ToList();
于 2020-11-27T18:32:36.993 回答
0

这对我使用 LINQ 有用...

lst1= lst2.ToList();
于 2021-05-14T12:50:05.530 回答