You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向列表添加对象实例避免引用覆盖导致的元素篡改问题?

问题解决:向列表添加对象时修改之前元素的问题

你的核心问题是引用类型的赋值逻辑错误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 21:27:53