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

C#中创建含对象的列表深拷贝失败,实现Clone方法仍无效

问题原因与解决方案

核心问题

你遇到的情况源于两个关键问题:

  • 列表构造函数new List<Person>(personList)执行的是浅拷贝:新列表本身是独立的集合,但列表中存储的是对象引用,secondList和personList里的元素指向同一个Person实例。修改secondList中对象的属性,本质还是修改原实例的属性。
  • 你实现了Clone方法,但代码里完全没调用这个方法,根本没创建对象的深拷贝副本。

修复方案

要创建包含独立对象副本的新列表,需要遍历原列表,对每个对象调用Clone方法,将克隆后的对象加入新列表。

修改主方法中的循环部分:

for(int i = 0; i < 3; i++)
{
    // 遍历原列表,克隆每个对象后创建新列表
    List<Person> secondList = personList.Select(person => (Person)person.Clone()).ToList();
    
    foreach(Person person in secondList)
    {
        person.sayMyName();
        Console.WriteLine(person.Age);
        person.Age--;
    }
    Console.WriteLine();
}

或者用手动遍历的方式:

for(int i = 0; i < 3; i++)
{
    List<Person> secondList = new List<Person>();
    foreach (var p in personList)
    {
        secondList.Add((Person)p.Clone());
    }
    
    foreach(Person person in secondList)
    {
        person.sayMyName();
        Console.WriteLine(person.Age);
        person.Age--;
    }
    Console.WriteLine();
}

额外优化建议

可以把Clone方法改为返回强类型,避免每次克隆都要强制转换:

// 在抽象类Person中修改
public abstract Person Clone();

// 在Student类中重写
public override Person Clone()
{
    return new Student(Name, Age, Grade);
}

这样主方法中的克隆代码可以简化为:

List<Person> secondList = personList.Select(person => person.Clone()).ToList();

注意事项

如果Person类后续添加了其他引用类型成员(比如自定义的Address类),需要在Clone方法中对这些成员也执行克隆操作,才能实现完全的深拷贝。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:15:38