为什么 C# 链表类变量在分配后不保留其值?



我正在创建一个填字游戏生成器,似乎在网格系统中有一个简单的坐标变量分配问题。我有一个非常简单的结构来保存离散的坐标值,如下所示。我剥离了封装,使其更易于阅读。

    public struct vec2
    {
        public int x, y;
        public vec2(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }

在类内部维护Vec2结构体,用于保存字值

public struct WordClass
{
    string svalue;
    bool flag;
    public vec2 position;
    public WordClass(string sarg, bool barg)
    {
        this.svalue = sarg;
        this.flag = barg;
        position = new vec2(0,0);
    }
    public string StringVal
    {
        get { return svalue; }
    }
    public bool FlagVal
    {
        get { return flag; }
    }
    public void DisableWord()
    {
        if (this.flipflop == false)
        {
            this.flipflop = true;
        }
    }
    public void SetPos(int xa, int ya)
    {
        this.position.x = xa;
        this.position.y = ya;
    }
}

这基本上应该维护一个带有使用标志的永久单词列表,以及一个可变位置,因为系统计算出单词的最佳位置。

我有一个动态的单词链表

    List<WordClass> WordList = new List<WordClass>();

和更改wordlist

中单词的坐标
    //Arbitrary values
    WordList[0].SetPos(Position_X, Position_Y);

现在我的问题是,当我尝试使用单词的位置时,无论我之前设置了什么,它都会保持默认值0,0。在做其他功能的时候,我一直在挠头,这让我怀疑我是否错过了一些重要的东西。

问题似乎与vec2ValueObject这一事实有关,而您正试图改变它。有问题的行具体是这两行:

this.position.x = xa;
this.position.y = ya;

为什么?因为vec2是一个struct,每次读取它时,您都会获得一个临时副本,然后修改该副本,然后将该副本丢弃,而您仍在读取原始的未修改的副本。这就是为什么值对象应该尽可能地不可变的一个原因,除非你有一个强有力的理由。

第一步应该是创建一个合适的不可变vec2结构:
public struct vec2
{
    public int x { get; private set; }
    public int y { get; private set; }
    public vec2(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

一旦您得到了这个,您需要注意SetPos方法中的修改。因为结构是不可变的,你不能再读取它,而是每次你需要改变它,你将扔掉当前的实例,并创建一个新的:

public void SetPos(int xa, int ya)
{
    this.position = new vec2(xa, ya);
}

这将创建一个全新的结构,并将其赋值给内部字段,其中包含新的值。因为这并不是真的试图修改结构,而是为一个新的结构改变结构,所以它不会受到同样微妙的错误的影响。

相关内容

  • 没有找到相关文章

最新更新