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

列表克隆后对象参数仍变更的C#技术问题求助

解决列表克隆后对象属性同步变更的问题

嘿,我完全懂你碰到的这个麻烦!这是.NET里非常典型的浅拷贝导致的引用共享问题,咱们来把它捋清楚并解决掉。

问题根源

你用new List<Crêpe>(Ordre)创建的新列表,本质上是做了一次浅拷贝:

  • 新列表本身是独立的,所以反转原列表的顺序不会影响克隆列表,这符合你的预期;
  • 但列表里的每个Crêpe元素,其实只是原列表中对应对象的引用——也就是说,两个列表里的同一个“位置”指向的是内存里的同一个Crêpe对象。所以当你修改原列表中对象的FaceCraméBienPlacé属性时,克隆列表里的对应对象自然也会跟着变化,因为它们根本就是同一个东西。

解决方案:实现深拷贝(真正复制每个对象)

要解决这个问题,你需要确保克隆列表时,不仅复制列表本身,还要复制每个Crêpe对象。这里有几种简单可行的方式:

方式1:给Crêpe类添加克隆方法

在你的Crêpe类里新增一个Clone()方法,用来创建当前对象的完全副本:

internal class Crêpe {
    internal int Nombre { get; set; }
    internal bool FaceCraméBienPlacé { get; set; }

    public Crêpe(int position, bool faceCraméBienPlacé) {
        Nombre = position;
        FaceCraméBienPlacé = faceCraméBienPlacé;
    }

    // 新增克隆方法,返回当前对象的独立副本
    public Crêpe Clone() {
        return new Crêpe(this.Nombre, this.FaceCraméBienPlacé);
    }
}

然后修改你克隆列表的代码,用Select逐个复制对象:

// 代替原来的 new List<Crêpe>(Ordre)
Solutions.Add(Ordre.Select(crêpe => crêpe.Clone()).ToList());

方式2:直接在克隆时创建新对象

如果不想给类加方法,也可以在克隆列表的时候直接通过构造函数创建新的Crêpe对象:

Solutions.Add(Ordre.Select(crêpe => new Crêpe(crêpe.Nombre, crêpe.FaceCraméBienPlacé)).ToList());

方式3:实现ICloneable接口(可选)

虽然.NET里ICloneable接口因为返回类型是object有点不便,但也是一种标准实现方式:

internal class Crêpe : ICloneable {
    internal int Nombre { get; set; }
    internal bool FaceCraméBienPlacé { get; set; }

    public Crêpe(int position, bool faceCraméBienPlacé) {
        Nombre = position;
        FaceCraméBienPlacé = faceCraméBienPlacé;
    }

    public object Clone() {
        return new Crêpe(this.Nombre, this.FaceCraméBienPlacé);
    }
}

克隆列表时需要做类型转换:

Solutions.Add(Ordre.Select(crêpe => (Crêpe)crêpe.Clone()).ToList());

验证效果

修改之后,你再修改原列表中Crêpe对象的FaceCraméBienPlacé属性时,克隆列表里的对象就不会同步变化了——因为它们现在是内存中完全独立的两个对象,只是初始属性值相同而已。

内容的提问来源于stack exchange,提问作者Zone2Risk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 19:57:38