无法修改Blackjack游戏中Player类Total属性值的技术问题
Total属性每次读取都会重新计算,直接覆盖了设置的值 嘿,我一眼就发现问题所在了——你定义的Total属性,每次读取它的时候都会重新计算手牌的总和,这就导致你用setter设置的0根本留不住!
咱们来拆解一下你的代码:
1. Total属性的核心问题
看你Player类里的Total属性实现:
public int Total { get { total = 0; // 每次读取都先把total重置为0 foreach (int card in hand) { total += card; // 然后重新计算手牌总和 } return total; } set { this.total = value; } }
你以为用player1.Total = 0把total字段设成0了,但只要接下来一读取player1.Total(比如后面的Console.WriteLine,甚至Bust属性的getter里调用Total),getter就会立刻把total重置为0,然后重新遍历hand计算总和——等于你设置的0直接被覆盖了!
2. Bust属性的额外问题
再看你的Bust属性:
private readonly int blackjack = 21; public bool Bust { get { return Bust = Total > blackjack; } private set { } }
这里的getter里写了return Bust = Total > blackjack,这是在给Bust属性赋值,但你的setter是空实现,完全没必要。而且每次访问Bust都会触发Total的getter,进一步加剧了“重新计算覆盖值”的问题。
解决方案:两种思路任选
思路1:让Total存储计算结果,只在手牌变化时更新
这种方式更高效,避免重复计算。我们把Total的getter改成直接返回存储的字段,然后通过方法来更新手牌和对应的total值:
修改后的Player类:
public class Player { private int total; private List<int> hand = new List<int>(); // 初始化手牌列表 public int Total { get { return total; } // 如果不需要外部直接设置Total,可以把set改成私有 private set { total = value; } } // 添加卡片时同步更新total public void AddCard(int card) { hand.Add(card); total += card; } // 重置手牌和total的方法 public void ResetHand() { hand.Clear(); total = 0; } // 修正Bust属性,直接返回判断结果 public bool Bust { get { return Total > 21; } } }
然后在Game类的CompareHands里,调用重置方法代替直接设置Total:
private void CompareHands() { // 测试输出 Console.WriteLine($"player total: {player1.Total}, is bust: {player1.Bust}"); Console.WriteLine($"house total: {house.Total}, is bust: {house.Bust}"); if (player1.Bust) player1.ResetHand(); if (house.Bust) house.ResetHand(); // 再次输出 Console.WriteLine($"player total: {player1.Total}, is bust: {player1.Bust}"); Console.WriteLine($"house total: {house.Total}, is bust: {house.Bust}"); // 后续逻辑... }
思路2:把Total做成只读计算属性,通过清空手牌来重置
如果你坚持让Total每次读取都计算(虽然没必要,重复计算影响性能),那可以去掉setter,因为Total的值完全由hand决定,设置它没有意义。要重置的话直接清空hand即可:
修改后的Player类片段:
public class Player { private List<int> hand = new List<int>(); // 只读属性,每次读取计算总和 public int Total { get { int sum = 0; foreach (int card in hand) sum += card; return sum; } // 去掉setter,因为它的值由hand决定 } public void ClearHand() { hand.Clear(); } public bool Bust { get { return Total > 21; } } }
然后Game类里改成:
if (player1.Bust) player1.ClearHand(); if (house.Bust) house.ClearHand();
这样下次读取Total时,因为hand是空的,自然会返回0。
内容的提问来源于stack exchange,提问作者user9409572

