C#控制台应用如何无需重复调用输出方法即可实时更新变量值
实现方案
方法1:使用INotifyPropertyChanged实现自动更新(推荐)
你可以让Player类实现属性变更通知接口,当health属性值发生变化时自动触发更新逻辑,全程不需要手动调用血量输出语句:
- 改造
Player类:
using System.ComponentModel; using System.Runtime.CompilerServices; public class Player : INotifyPropertyChanged { public string name { get; set; } private int _health; public int health { get => _health; set { _health = value; // 属性变更时触发通知事件 OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
- 改造
StartFight方法,订阅属性变更事件自动更新控制台:
public static void StartFight(Player p1, Player p2) { Console.Clear(); Title(" BATTLE "); // 记录两行血量显示的固定行号,后续直接覆盖更新不需要重复输出 int p1HealthLine = Console.CursorTop; Console.WriteLine($"{p1.name} Health: {p1.health} "); int p2HealthLine = Console.CursorTop; Console.WriteLine($"{p2.name} Health: {p2.health} "); // 订阅p1的属性变更事件,血量变化自动更新对应行 p1.PropertyChanged += (s, e) => { if (e.PropertyName == nameof(Player.health)) { Console.SetCursorPosition(0, p1HealthLine); Console.Write($"{p1.name} Health: {p1.health} "); // 光标归位不影响后续其他内容输出 Console.SetCursorPosition(0, Console.CursorTop); } }; // 订阅p2的属性变更事件 p2.PropertyChanged += (s, e) => { if (e.PropertyName == nameof(Player.health)) { Console.SetCursorPosition(0, p2HealthLine); Console.Write($"{p2.name} Health: {p2.health} "); Console.SetCursorPosition(0, Console.CursorTop); } }; // 原有战斗逻辑完全不需要修改,不需要加任何血量输出语句 while (true) { if (Fight(p1, p2)) { Title(" GAME OVER! "); PlayAgain(); break; } if (Fight(p2, p1)) { Title(" GAME OVER! "); PlayAgain(); break; } } }
方法2:封装更新方法(轻量需求可选)
如果你不想改动Player类的结构,可以把血量更新逻辑封装成独立方法,只需要在循环里调用一次就行,不需要重复写整段输出代码:
// 全局记录血量显示的行号 static int p1HealthLine, p2HealthLine; public static void UpdateHealth(Player p1, Player p2) { Console.SetCursorPosition(0, p1HealthLine); Console.Write($"{p1.name} Health: {p1.health} "); Console.SetCursorPosition(0, p2HealthLine); Console.Write($"{p2.name} Health: {p2.health} "); Console.SetCursorPosition(0, Console.CursorTop); }
之后只需要在每次Fight方法执行后调用UpdateHealth(p1,p2)即可。
注意:使用SetCursorPosition覆盖输出的方式比反复清屏的效率更高,也不会出现屏幕闪烁的问题。
内容的提问来源于stack exchange,提问作者ac88
相关产品推荐
相关产品推荐

