C# 如何在不引用原始 List<T> 的情况下分配 List<T>?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13447248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 08:35:15  来源:igfitidea点击:

How to assign List<T> without it being a reference to the original List<T>?

c#reference

提问by TheScholar

For example

例如

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

later in the code:

稍后在代码中:

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

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

So, from this point I would like to keep adding element or making changes in name_list2 without affecting name_list1. How do I do that?

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

采纳答案by Inisheer

name_list2 = new List<string>(name_list1);

This will clone the list.

这将克隆列表。

回答by Dmitry Frenkel

name_list2 = new List<string>(name_list1); // Clone list into a different object

At this point, the two lists are different objects. You can add items to list2 without affecting list1

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

回答by adv12

The problem is the assignment. Until the assignment name_list2 = name_list1;, you have two different List objects on the heap pointed to by the variables name_list1and name_list2. You fill up name_list1, which is fine. But the assignment says, "make name_list2point to the same object on the heap as name_list1." The List that name_list2used to point to is no longer accessible and will be garbage collected. What you really want is to copy the contentsof name_list1into name_list2. You can do this with List.AddRange. Note that this will result in a "shallow" copy, which is fine for the example you cite, where the list contents are strings, but may not be what you want when the list members are more complex objects. It all depends on your needs.

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

回答by ayc

Another Options is : Deep Cloning

另一种选择是:深度克隆

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;
        }

so,

所以,

you can use :

您可以使用 :

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

OR:

或者:

name_list2 = DeepCopy(name_list1); 

will also work.

也会起作用。

回答by A.Clymer

Here is an alternative solution:

这是一个替代解决方案:

    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());

The ToArray() method copies 'name_list1' to a new array, which we then add to name_list2 via the AddRange() method.

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

回答by u8it

I like linq for this...

我喜欢 linq 为此...

If list elements are primitives or structures then...

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

L2 = L1.ToList()

If list elements are classes then...

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

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

Where Copycould simply be a shallow copy exposure of MemberWiseClone, or it could be some implementation of a deep copy.

哪里Copy可能只是浅拷贝暴露MemberWiseClone,或者它可能是深拷贝的某种实现。

回答by Mrunal Brahmbhatt

I prefer Json converter method to serialize and deserialize, this way you don't have to mark the classes for serialization, especially you have numerous child classes.

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

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

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

回答by Palash Roy

For primitive types:
List ClonedList = new list(OriginalList);

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

For non-primitive/User Defined types:
We need to perform a deep copy: Deep Copy is used to make a complete deep copy of the internal reference types, for this we need to configure the object returned by MemberwiseClone().

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

Step1- In your class inherit from ICloneable:
public class MyClass:ICloneable

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

Step2- Implement method

Step2- 实现方法

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

Step3- now clone your List

Step3- 现在克隆您的列表

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

This will make deep copy of each item of the object.

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

回答by Chris Keefer

None of the above solutions worked for me when using lists of class objects.

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

This can be used for copying any object to another object with shared property names.

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

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;
}

For lists use this: list2 = list1.CopyList();

对于列表使用这个: list2 = list1.CopyList();

回答by davinceleecode

For Primitive Types you can do this:

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

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

For non-primitve/user-difined types you can do this:

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

List<Person> CopyList = new List<Person>();
foreach(var item in OriginalList)
{
    CopyList.Add(new Person { 
            Name = item.Name,
            Address = item.Address
    });
}