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

多次实例化Game类却共享内存状态的技术问题求助

问题根源:引用类型的浅拷贝导致状态共享

你遇到的核心问题是**浅拷贝(Shallow Copy)**搞的鬼:你的Game类里的playerCards是引用类型(比如List<string>),而当前的Clone方法只是把原实例的列表引用直接传给了新实例,根本没创建列表的独立副本。这就导致所有通过Clone生成的Game实例,实际上共用同一个playerCards列表——改其中任何一个的列表,其他所有实例都会同步跟着变。

解决方案:实现深拷贝(Deep Copy)

要解决这个问题,你得在Clone方法里对所有引用类型的成员做深拷贝,也就是给它们创建独立的新实例,而不是直接传递原引用。

1. 修改Game的Clone方法

假设playerCards和dealerCards是List<string>类型,修改后的Clone方法要为这些列表创建全新的副本:

public Game Clone() 
{
    // 为列表创建独立副本:用原列表的元素初始化新List
    var clonedPlayerCards = new List<string>(playerCards);
    var clonedDealerCards = new List<string>(dealerCards);
    
    return new Game(
        clonedPlayerCards, 
        clonedDealerCards, 
        playerHasStood, 
        playerHasSplit, 
        playerHasDoubled
    );
}

// 带参数的Clone重载也一样处理:
public static Game Clone(Game game) 
{
    var clonedPlayerCards = new List<string>(game.playerCards);
    var clonedDealerCards = new List<string>(game.dealerCards);
    
    return new Game(
        clonedPlayerCards, 
        clonedDealerCards, 
        game.playerHasStood, 
        game.playerHasSplit, 
        game.playerHasDoubled
    );
}

2. 检查Shoe类的Clone方法

同理,你的Shoe类里如果有引用类型成员(比如除了int类型的卡片计数外,还有其他自定义对象或列表),也要做同样的深拷贝处理。如果只是int这种值类型,那不用额外操作,但一定要确保所有引用类型成员都被独立复制。

3. 验证效果

修改完成后,每个通过Clone创建的Game实例都会拥有完全独立的playerCards列表。当你调用g.AddPlayerCard(card)时,只会修改当前实例的列表,其他分支里的Game实例状态不会被影响。

额外小提示

如果后续你的类可能添加更多引用类型成员,建议实现ICloneable接口,或者封装一个统一的深拷贝逻辑,避免每次新增成员都要修改Clone方法。另外,也可以用序列化/反序列化的方式实现通用深拷贝(比如用Json.NET序列化后再反序列化),但对于简单的类,手动深拷贝效率会更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:18:25