结构变量不变

Neo*_*uro 1 c# struct unity-game-engine

我觉得我错过了一些完全明显的东西,所以我提前道歉(如果?)就是这种情况.我正在尝试做一些非常简单的事情,将结构中的bool值从false更改为true.显然我不能直接更改它,所以我在结构中创建了一个我可以调用的方法,它应该改变那里的值.似乎并非如此.这是代码,我很欣赏任何见解;

public Dictionary<int, List<ScanLineNode>> allScanLineNodes = new Dictionary<int, List<ScanLineNode>>();

public void MethodName(ScanLineNode node [...])
{       
    //This will perform a raycast from the Node's position in the specified direction. If the raycast hits nothing, it will return Vector3.zero ('Row is complete'), otherwise will return the hit point

    Vector3 terminationPoint = node.RaycastDirection(node, direction, maxDist, targetRaycast, replacementColour, backgroundColour);

    ScanLineNode terminationNode = new ScanLineNode();

    //Previously attempted to store a local reference to this row being used, but also did not work
    //List<ScanLineNode> rowNodes = allScanLineNodes[node.rowNumber];

    [...]

    if (terminationPoint == Vector3.zero)
    {
        //Definitely reaches this point, and executes this function along the row, I have added breakpoints and checked what happens in this for loop. After running 'RowComplete' (which just changes 'rowComplete' from false to true) 'rowComplete' is still false. Just in case I've included the RowComplete() function below.

        Debug.Log("Row Complete: " + node.rowNumber);
        for (int i = 0; i < allScanLineNodes[node.rowNumber].Count; i++)
        {
            allScanLineNodes[node.rowNumber][i].RowCompleted();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ScanLineNode Struct - 大多数东西都是隐藏的(我不相信会影响这个),但我已经包含了RowComplete()函数.

public struct ScanLineNode
    {
        [...]
        public bool rowComplete;
        [...]

        public ScanLineNode([...])
        {
            [...]
            rowComplete = false;
            [...]
        }

        public void RowCompleted()
        {
            rowComplete = true;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我还确认RowCOmpleted()不会在上面的位置被调用,并且'rowComplete'只能从RowComplete()函数中调用

Mar*_*ell 7

(来自评论) allScanLineNodes is a Dictionary<int, List<ScanLineNode>>

对; a的索引器List<ScanLineNode>返回结构的副本.因此,当您调用该方法时 - 您在堆栈上的断开连接的值上调用它,片刻之后会蒸发(在堆栈上被覆盖 - 这不是垃圾收集器).

这是可变结构的常见错误.你最好的选择可能是:不要制作可变的结构.但是......你可以复制它,改变它,然后将变异的值推回:

var list = allScanLineNodes[node.rowNumber];
var val = list[i];
val.RowCompleted();
list[i] = val; // push value back in
Run Code Online (Sandbox Code Playgroud)

但是不可变通常更可靠.

注意:您可以摆脱这跟阵列,因为从一个数组索引提供了访问参考,以就地结构-而不是复制的价值.但是:这不是一个建议,因为依赖这种微妙的差异会导致混乱和错误.