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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:48:39