ASP.NET Core中修改clone列表为何同步改动lista,类似C指针效果?
核心原因
- C#中
class为引用类型,变量存储的是堆对象的内存地址,行为逻辑和C语言指针类似。你代码中用到的WeatherForecast默认是类,属于引用类型。 - 你代码中的
clone = lista并未实现列表克隆,仅将clone变量指向了和lista完全相同的List<WeatherForecast>实例,二者操作的是同一个列表对象。
代码执行逻辑拆解
- 执行LINQ查询后,
lista指向堆上的一个List<WeatherForecast>实例,列表内部存储2个WeatherForecast对象的引用 clone = lista执行后,两个变量持有同一个列表的引用,列表内部存储的元素引用也完全一致- 修改
clone[0].Date本质是修改二者共同指向的第一个WeatherForecast对象的属性,因此通过lista访问对应元素时,自然会读取到修改后的值
实现独立修改的解决方案
浅克隆(仅列表增删互不影响,修改元素属性仍会同步)
仅复制列表结构,内部元素仍为原有引用:
clone = new List<WeatherForecast>(lista); // 等价写法:clone = lista.ToList();
深克隆(列表和元素修改完全独立)
需要为每个WeatherForecast元素创建新副本后存入新列表:
clone = lista.Select(item => new WeatherForecast { Date = item.Date, TemperatureC = item.TemperatureC, Summary = item.Summary }).ToList(); // 若WeatherForecast为C# 9+的record类型,可简化为: // clone = lista.Select(item => item with {}).ToList();
内容的提问来源于stack exchange,提问作者elidexter
相关产品推荐
相关产品推荐

