C#中修改临时对象artemp为何会同步更新原列表的ar对象?
C# 对象引用修改问题解决
你的代码里出现修改artemp.name会同步改变ar.name的问题,核心原因是AnalyticResult是引用类型,当你执行artemp = ar时,并没有创建新的对象,只是让artemp和ar指向内存中同一个对象实例。所以修改其中一个的属性,另一个自然会跟着变。
要实现只修改artemp而不影响原对象ar,你需要创建一个原对象的副本,而不是直接赋值引用。以下是几种常见的实现方式:
1. 手动复制属性
如果你的AnalyticResult没有拷贝构造函数,可以逐个复制原对象的属性到新创建的对象中:
List<AnalyticResult> listanalytic = new List<AnalyticResult>(); foreach(AnalyticResult ar in listanalytic){ AnalyticResult artemp = new AnalyticResult(); // 复制ar的所有属性到artemp artemp.Id = ar.Id; artemp.Value = ar.Value; // ... 其他需要复制的属性 // 单独修改name属性 artemp.name = name; }
2. 实现拷贝构造函数
给AnalyticResult添加一个拷贝构造函数,方便快速创建对象副本:
public class AnalyticResult { public string name { get; set; } public int Id { get; set; } // 其他属性... // 拷贝构造函数 public AnalyticResult(AnalyticResult original) { name = original.name; Id = original.Id; // 复制其他属性 } }
然后在循环中使用拷贝构造函数创建副本:
foreach(AnalyticResult ar in listanalytic){ AnalyticResult artemp = new AnalyticResult(ar); artemp.name = name; }
3. 使用对象初始化器简化代码
可以结合对象初始化器,在创建新对象时直接复制属性并修改目标值:
foreach(AnalyticResult ar in listanalytic){ AnalyticResult artemp = new AnalyticResult { Id = ar.Id, Value = ar.Value, // ... 其他属性 name = name // 直接设置新的name }; }
4. 如果是C# 9+的记录类型(Record)
如果AnalyticResult是用record定义的,可以直接使用with表达式快速创建修改后的副本:
public record AnalyticResult(string name, int Id); // 循环中创建副本并修改name foreach(AnalyticResult ar in listanalytic){ AnalyticResult artemp = ar with { name = name }; }
内容的提问来源于stack exchange,提问作者Sathish PS
相关产品推荐
相关产品推荐

