使用list1.AddRange(list2)时,如何修改list2的值不影响list1?
问题解决:添加对象到列表后修改原列表不影响新列表
你遇到的核心问题是引用类型的引用传递特性:list1.AddRange(list2)只是把list2中对象的引用复制到list1里,两个列表指向的是同一批对象实例。所以修改list2中的对象属性,list1里的对应对象也会跟着变化。
要让list1不受影响,你需要给list1添加原对象的副本,而不是原对象的引用。以下是几种可行的实现方式:
1. 给自定义类添加克隆方法
如果你的对象是自定义类,比如:
public class MyItem { public int Value { get; set; } }
可以给类添加一个克隆方法,创建新的对象实例并复制属性:
public class MyItem { public int Value { get; set; } // 自定义克隆方法,复制当前对象的属性到新实例 public MyItem Clone() { return new MyItem { Value = this.Value }; } }
然后替换AddRange为遍历添加克隆对象:
// 替代AddRange,添加每个对象的副本 foreach (var item in list2) { list1.Add(item.Clone()); } // 此时修改list2的对象,不会影响list1 foreach (var item in list2) { item.Value--; }
2. 使用LINQ直接生成新对象
如果不想修改原类,可以在添加时用Select直接创建新对象:
// 用Select生成每个item的新实例,再添加到list1 list1.AddRange(list2.Select(item => new MyItem { Value = item.Value }));
3. 使用C#记录类型(Record)
如果你的对象适合用值语义,可以改用C# 9.0引入的记录类型,记录默认支持基于属性的复制:
// 定义记录类型 public record MyItem(int Value);
添加时直接复制对象(或使用with语法创建新实例):
// 添加原对象的副本到list1 list1.AddRange(list2.Select(item => item with { })); // 修改list2的对象不会影响list1 foreach (var item in list2) { list2 = list2.Select(x => x with { Value = x.Value - 1 }).ToList(); }
内容的提问来源于stack exchange,提问作者Anh Đinh
相关产品推荐
相关产品推荐

