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

The*_*lar 51 c# reference

例如

List<string> name_list1 = new List<string>();
List<string> name_list2 = new List<string>();
Run Code Online (Sandbox Code Playgroud)

稍后在代码中:

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

name_list2 = name_list1; // I make a copy of namelist1 to namelist2
Run Code Online (Sandbox Code Playgroud)

所以,从这一点来说,我想继续添加元素或在name_list2中进行更改,而不会影响name_list1.我怎么做?

Ini*_*eer 119

name_list2 = new List<string>(name_list1);
Run Code Online (Sandbox Code Playgroud)

这将克隆列表.

  • 这仍然引用name_list1 (41认同)
  • @Dev这仅适用于原始类型,即字符串列表.如果您有一个复杂的对象,那么它将无法工作,您将需要使用深度克隆或创建另一个列表,就像您创建第一个列表一样. (16认同)
  • 这只适用于原始类型,它应该添加到问题中. (6认同)
  • 这是一个不错的清洁解决方案。为了澄清起见,请允许我添加一下,不要在上面的几行中使用“ new List &lt;string&gt;()”构造函数来初始化name_list2,因为您将创建一个对象以将其丢弃。没什么大不了的,但是要养成不良的编码习惯。 (2认同)

Dmi*_*kel 8

name_list2 = new List<string>(name_list1); // Clone list into a different object
Run Code Online (Sandbox Code Playgroud)

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

  • "你可以在不影响list1的情况下将项目添加到list2",这是错误的. (4认同)
  • 那对我不起作用。它仍然在引用。我用这个代替 http://stackoverflow.com/a/25035202/1367450 (3认同)
  • 您可以在不影响list1的情况下添加和删除list2,但是更新项目时,它将在两个列表中传播 (2认同)

dav*_*ode 6

For Primitive Types you can do this:

List<string> CopyList = new List<string>(OriginalList);
Run Code Online (Sandbox Code Playgroud)

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
    });
}
Run Code Online (Sandbox Code Playgroud)


adv*_*v12 5

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


aru*_*aru 5

另一个选择是:深度克隆

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;
        }
Run Code Online (Sandbox Code Playgroud)

所以,

您可以使用 :

name_list2 = DeepCopy<List<string>>(name_list1);
Run Code Online (Sandbox Code Playgroud)

要么:

name_list2 = DeepCopy(name_list1); 
Run Code Online (Sandbox Code Playgroud)

也可以。

  • 不错的解决方案,但请记住,如果类是“引用类型”,则始终需要在类上具有“ Serializable”属性。 (2认同)
  • 如果改为`Clone&lt;T&gt;(this T item)`,甚至会更好一点,所以它可以被称为`name_list2=name_list1.Clone()` 恕我直言 (2认同)

u8i*_*8it 5

我喜欢 linq 这个...

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

L2 = L1.ToList()
Run Code Online (Sandbox Code Playgroud)

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

L2 = L1.Select(x => x.Copy()).ToList();
Run Code Online (Sandbox Code Playgroud)

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