如何向列表添加对象实例避免引用覆盖导致的元素篡改问题?
问题解决:向列表添加对象时修改之前元素的问题
你的核心问题是引用类型的赋值逻辑错误:DocRequisicionTransferModel是引用类型,循环中你先创建了新实例,随后立刻执行doctoReqTransfer = docRequisicionTransferModel;,这等于让新变量直接指向原对象的内存地址,并没有真正创建独立的新对象。后续对doctoReqTransfer的属性修改,本质都是在修改同一个原对象,列表里的所有元素都是这个原对象的引用,所以每次添加新元素时,之前的元素也会跟着变化。
解决方案1:手动复制属性创建新实例
直接创建新的DocRequisicionTransferModel实例,手动复制原对象中需要保留的属性,再修改目标属性:
private List<DocRequisicionTransferModel> sendReqMultiple(DocRequisicionTransferModel docRequisicionTransferModel) { List<DocRequisicionTransferModel> data = new List<DocRequisicionTransferModel>(); List<MovRequisicionTransferModel> movRequisicionTransferModels = docRequisicionTransferModel.MovimientoRequisicionTransferencia; List<String> distinctBodegas = docRequisicionTransferModel.MovimientoRequisicionTransferencia.Select(movto => movto.IdBodegaSal).Distinct().ToList(); foreach (String bodega in distinctBodegas) { if (!String.IsNullOrEmpty(bodega)) { // 创建全新的实例,而非引用原对象 DocRequisicionTransferModel doctoReqTransfer = new DocRequisicionTransferModel(); // 手动复制原对象的其他属性(根据你的实际类结构补充所有需要保留的属性) // 示例:假设类中有这些属性需要复制 doctoReqTransfer.SomeProperty = docRequisicionTransferModel.SomeProperty; doctoReqTransfer.AnotherProperty = docRequisicionTransferModel.AnotherProperty; // 修改当前循环需要的属性 doctoReqTransfer.IdBodegaSal = bodega; doctoReqTransfer.MovimientoRequisicionTransferencia = movRequisicionTransferModels.Where(movto => movto.IdBodegaSal.Equals(bodega)).ToList(); data.Add(doctoReqTransfer); } } return data; }
解决方案2:实现克隆方法(更优雅的复用方式)
给DocRequisicionTransferModel实现ICloneable接口,实现克隆逻辑(注意如果类中包含其他引用类型属性,需要考虑深克隆):
第一步:给模型添加克隆方法
public class DocRequisicionTransferModel : ICloneable { // 你的现有属性... public string IdBodegaSal { get; set; } public List<MovRequisicionTransferModel> MovimientoRequisicionTransferencia { get; set; } // 其他属性... public object Clone() { // 先执行浅克隆 DocRequisicionTransferModel clone = (DocRequisicionTransferModel)this.MemberwiseClone(); // 对于List这类引用类型属性,需要重新创建列表避免共享引用 clone.MovimientoRequisicionTransferencia = new List<MovRequisicionTransferModel>(this.MovimientoRequisicionTransferencia); // 如果还有其他引用类型属性,同样需要单独处理 return clone; } }
第二步:在循环中使用克隆方法
private List<DocRequisicionTransferModel> sendReqMultiple(DocRequisicionTransferModel docRequisicionTransferModel) { List<DocRequisicionTransferModel> data = new List<DocRequisicionTransferModel>(); List<MovRequisicionTransferModel> movRequisicionTransferModels = docRequisicionTransferModel.MovimientoRequisicionTransferencia; List<String> distinctBodegas = docRequisicionTransferModel.MovimientoRequisicionTransferencia.Select(movto => movto.IdBodegaSal).Distinct().ToList(); foreach (String bodega in distinctBodegas) { if (!String.IsNullOrEmpty(bodega)) { // 通过克隆创建独立的新对象 DocRequisicionTransferModel doctoReqTransfer = (DocRequisicionTransferModel)docRequisicionTransferModel.Clone(); // 修改当前循环的目标属性 doctoReqTransfer.IdBodegaSal = bodega; doctoReqTransfer.MovimientoRequisicionTransferencia = movRequisicionTransferModels.Where(movto => movto.IdBodegaSal.Equals(bodega)).ToList(); data.Add(doctoReqTransfer); } } return data; }
内容的提问来源于stack exchange,提问作者Janer Leonardo Tegue
相关产品推荐
相关产品推荐

