C#如何可靠地将Main方法中的功能代码迁移到其他自定义类中
实现步骤
我们先把现有逻辑封装到一个独立的GridMover类中,这个类可以直接复用到其他需要网格移动的控制台项目中:
- 把原来Main方法里的地图尺寸、坐标变量全部转为类的私有字段,作为类的内部状态维护
- 把输入处理、坐标更新、画面渲染的逻辑拆分为独立方法,方便后续修改扩展
- 对外暴露可配置的参数和启动方法,调用时不需要关心内部实现细节
封装后的类代码
using System; // 可复用的网格移动类 public class GridMover { // 私有状态字段,维护类内部数据 private readonly int _xLength; private readonly int _yLength; private readonly int _maxMoveSteps; private readonly string _playerMark; private int _oldPositionX; private int _oldPositionY; private int _newPositionX; private int _newPositionY; // 构造函数:对外暴露可配置的参数,默认值可以根据需求调整 public GridMover(int xLength = 20, int yLength = 20, int maxMoveSteps = 100, string playerMark = ".") { // 修正原代码中xLentgh的拼写错误 _xLength = xLength; _yLength = yLength; _maxMoveSteps = maxMoveSteps; _playerMark = playerMark; } // 对外暴露的启动方法,直接调用即可运行完整逻辑 public void Run() { // 初始化地图 Map.MapBuilder(_xLength, _yLength); // 初始化玩家初始位置 _newPositionX = _oldPositionX = 0; _newPositionY = _oldPositionY = 0; Map.WriteAt(_playerMark, _newPositionX, _newPositionY); // 主循环逻辑 for (int i = 0; i < _maxMoveSteps; i++) { ConsoleKeyInfo keyStroke = Console.ReadKey(); ProcessInput(keyStroke.Key); UpdateRender(); } } // 输入处理逻辑,单独拆分后方便后续新增自定义按键 private void ProcessInput(ConsoleKey key) { // 先记录移动前的坐标 _oldPositionX = _newPositionX; _oldPositionY = _newPositionY; switch (key) { case ConsoleKey.RightArrow: if (_newPositionX < _xLength - 1) _newPositionX++; break; case ConsoleKey.LeftArrow: if (_newPositionX > 0) _newPositionX--; break; case ConsoleKey.UpArrow: if (_newPositionY > 0) _newPositionY--; break; case ConsoleKey.DownArrow: if (_newPositionY < _yLength - 1) _newPositionY++; break; default: // 非方向键不移动,回滚旧坐标 _oldPositionX = _newPositionX; _oldPositionY = _newPositionY; break; } } // 画面更新逻辑,单独拆分后方便后续修改渲染效果 private void UpdateRender() { // 只有坐标变化才更新画面,避免无意义的渲染 if (_oldPositionX == _newPositionX && _oldPositionY == _newPositionY) return; Map.WriteAt(_playerMark, _newPositionX, _newPositionY); Map.WriteAt(" ", _oldPositionX, _oldPositionY); } }
Main方法调用方式
原来的Main方法只需要保留几行代码即可,逻辑清晰:
static void Main() { // 可以自定义参数,比如要30*30的地图、最多移动200步就传参:new GridMover(30,30,200) var mover = new GridMover(); mover.Run(); }
后续扩展提示
如果需要进一步复用,可以做以下调整:
- 把
Map类的静态方法改为依赖注入,适配不同的地图渲染实现 - 新增移动完成的事件回调,其他逻辑可以监听玩家移动事件做对应处理
- 新增障碍物碰撞判断逻辑,只需要修改
ProcessInput方法里的坐标校验规则即可
内容的提问来源于stack exchange,提问作者Rarowcun
相关产品推荐
相关产品推荐

