C#调用静态类成员获取int坐标值返回异常值问题求助
为减少代码重复逻辑,我设计了一个全局共享的静态类Coordinate,用于存储所有游戏对象的坐标,对外提供坐标获取、更新的相关方法,该类实现代码如下:
// A static class, that holds all object's coordinates, and methods to return & update their values. internal static class Coordinate { private static int[,] PlayerCoordinate { get; set; } public static int[,] GateCoordinate { get; } public static int[,] FountainCoordinate { get; } static Coordinate() // FIRST VALUE IS X (column), SECOND VALUE IS Y (row). { PlayerCoordinate = new int[,] { { 0, 0 } }; GateCoordinate = PlayerCoordinate; // Just starts off in the same place as player. FountainCoordinate = new int[,] { { 2, 0 } }; } // A static method, that sends the data of all object coordinates, deconstructed into seperate ints. public static int PlayerColumn() { return PlayerCoordinate[0, 0]; } public static int PlayerRow() { return PlayerCoordinate[0, 1]; } public static int GateColumn() { return GateCoordinate[0, 0]; } public static int GateRow() { return GateCoordinate[0, 1]; } public static int FountainColumn() { return FountainCoordinate[0, 0]; } public static int FountainRow() { return FountainCoordinate[0, 1]; } // Updates the coordinates of the player. public static void UpdatePlayerCoordinate(int column, int row) { PlayerCoordinate = new int[,] { { column, row } }; } }
程序核心运行逻辑在GameManager类中,预期启动后控制台输出You are in the room at (Column=0, Row=0),实际输出了异常的奇怪值,异常输出截图如下:
GameManager类实现代码如下:
internal class GameManager { private bool IsGameOver; private Player Player; private Updater Updater; // Don't need to call Fountain or Coordinate since they're static public GameManager() { IsGameOver = false; Player = new(); Updater = new(); } public void RunGame() { while (!IsGameOver) { Console.WriteLine("----------------------------------------------------------"); Updater.DisplayPlayerPosition(); // 问题出在这行 Updater.DisplayPlayerSenses(); string playerInput = Player.GetInput(); Updater.MovePlayer(playerInput); IsGameOver = Updater.CheckForWin(); } } }
问题对应的Updater类方法代码如下:
internal class Updater { // 无字段 // 默认构造函数 // 输出玩家当前位置文本 public void DisplayPlayerPosition() // 问题方法 { Console.WriteLine($"You are in the room at (Column={Coordinate.PlayerColumn}, Row={Coordinate.PlayerRow})"); } // 其余方法省略... }
我接触static关键字时间不长,怀疑是Coordinate类未完成初始化导致问题——我没有手动调用该类的构造函数,且了解到静态构造函数无法手动调用,需要问题排查指导。
异常输出和静态构造函数初始化无关,C#静态构造函数会在第一次访问类的静态成员前自动执行,不需要手动调用,你的静态类初始化逻辑会正常触发。
真正的问题是你在输出时没有正确调用坐标获取方法:PlayerColumn和PlayerRow是你定义的静态方法,C#中调用方法必须在方法名后加()传参(无参数也要加空括号),你直接写方法名的写法,输出的是「方法组」的默认字符串表现(也就是方法的全限定名),完全不会执行方法内部的返回坐标逻辑,所以才会出现和预期不符的奇怪输出。
另外你的代码还存在一个隐藏逻辑bug:静态构造函数中GateCoordinate = PlayerCoordinate是数组引用赋值,初始时两个变量指向同一个数组,但你更新玩家坐标时是每次new一个新数组赋值给PlayerCoordinate,此时GateCoordinate仍然指向最初的{0,0}数组,不会同步玩家位置变化,如果你的预期是传送门初始位置和玩家一致、后续不跟随玩家移动则无影响,如果需要同步位置则要调整更新逻辑。
- 修正
DisplayPlayerPosition方法中的方法调用,给两个坐标获取方法加上括号,正确拿到返回值:public void DisplayPlayerPosition() { Console.WriteLine($"You are in the room at (Column={Coordinate.PlayerColumn()}, Row={Coordinate.PlayerRow()})"); } - 根据业务逻辑校验
GateCoordinate的引用赋值问题,如果需要传送门跟随玩家移动,就不要在更新坐标时创建新数组,直接修改原数组的元素值即可。
内容的提问来源于stack exchange,提问作者Om Khadka

