C# 结构变量不变

C# 结构变量不变,c#,unity3d,struct,C#,Unity3d,Struct,我觉得我错过了一些非常明显的东西,所以我提前道歉,如果什么时候?情况就是这样。 我试图做一些非常简单的事情,将结构中的bool值从false改为true。显然,我不能直接更改它,所以我在结构中创建了一个方法,我可以调用它,该方法应该更改那里的值。事实似乎并非如此。这是代码,如果您有任何见解,我将不胜感激 public Dictionary<int, List<ScanLineNode>> allScanLineNodes = new Dictionary<int,

我觉得我错过了一些非常明显的东西,所以我提前道歉,如果什么时候?情况就是这样。 我试图做一些非常简单的事情,将结构中的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();
        }
    }
}

我还确认RowCOmpleted不会在上述位置之外的任何位置被调用,并且“rowComplete”只会从rowComplete函数调用

对,;列表的索引器返回结构的副本。因此,当您调用该方法时——您是在堆栈上一个断开连接的值上调用它,该值在稍后蒸发,并在堆栈上被覆盖——这不是垃圾收集器

这是可变结构的常见错误。您最好的选择可能是:不要创建可变结构。但是您可以将其复制、变异,然后将变异后的值推回:

var list = allScanLineNodes[node.rowNumber];
var val = list[i];
val.RowCompleted();
list[i] = val; // push value back in
但不可变通常更可靠


注意:使用数组可以避免这种情况,因为数组的索引器提供对就地结构的引用的访问,而不是值的副本。但是:这不是一个建议,因为依赖这种细微的差异可能会导致混淆和错误。

从注释中可以看出,allScanLineNodes是一本字典

对,;列表的索引器返回结构的副本。因此,当您调用该方法时——您是在堆栈上一个断开连接的值上调用它,该值在稍后蒸发,并在堆栈上被覆盖——这不是垃圾收集器

这是可变结构的常见错误。您最好的选择可能是:不要创建可变结构。但是您可以将其复制、变异,然后将变异后的值推回:

var list = allScanLineNodes[node.rowNumber];
var val = list[i];
val.RowCompleted();
list[i] = val; // push value back in
但不可变通常更可靠


注意:使用数组可以避免这种情况,因为数组的索引器提供对就地结构的引用的访问,而不是值的副本。但是:这不是一个建议,因为依赖这种细微的差异可能会导致混淆和错误。

什么是allScanLineNodes[node.rowNumber][i]?这些索引器是否位于数组、列表或字典上确实很重要,例如allScanLineNodes是一个字典什么是allScanLineNodes[node.rowNumber][i]?这些索引器是否在数组、列表或字典上真的很重要,例如AllScanlineNodes是一个字典,我认为这与它是一个值类型有关,但它们仍然让我困惑,哈哈。我以前听过immutable/mutable,但仍然不能100%确定它是什么。根据您的建议,当我想要更改“RowCompleted”时,是否最好创建一个新的结构实例并将该值放入?IE allScanLineNodes[x][y]=新的ScanLineNode。。。。。。。。尽管如此,我刚刚意识到我使用了一种类似的方法来改变另一个值,一个存储的颜色变量,它肯定会起作用。我使用一种方法根据传入的颜色更改颜色变量。@NeoKuro该颜色是否可能位于公共字段而不是属性上?或者在一个数组中,而不是列表中——这就解释了为什么它在这个数组中工作case@NeoKuro不可变类型是一种根本无法更改内部值的类型。您可以做的是创建一个新的相似值,该值具有相似的值,可能具有一个或两个不同的值-并将该不同的值写入要替换的值的顶部(据我所知,它是一个常规字段),就像布尔行完成一样。我现在已经将所有字段都转换为private,并使其中一些字段仅可由getter属性公开访问。当我创建结构的新“副本”时,使用我想要的新数据(如您所说),它似乎工作正常。但正如我所说的,无论哪种情况,颜色场都可以正常工作。我还想知道使用'ref'关键字是否也不正确?这似乎也引起了我的问题,尽管rowComplete在字典中已经更改,但在Method中的local'node'参数中没有更改。我认为这与它是一种值类型有关。它们仍然让我感到困惑哈哈。我以前听过immutable/mutable,但仍然不能100%确定它是什么。根据您的建议,当我想要更改“RowCompleted”时,是否最好创建一个新的结构实例并将该值放入?IE allScanLineNodes[x][y]=新的ScanLineNode。。。。。。。。尽管如此,我刚刚意识到我使用了一种类似的方法来改变另一个值,一个存储的颜色变量,它肯定会起作用。我使用一种方法根据传入的颜色更改颜色变量。@NeoKuro该颜色是否可能位于公共字段而不是属性上?或者在一个数组中,而不是列表中——这就解释了为什么它在这个数组中工作case@NeoKuro不可变类型是一种根本无法更改内部值的类型。您可以做的是创建一个新的类似值,该值可能与
一个或两个不同的值-并将不同的值写在要替换的值的顶部,我可以说它是一个常规字段,就像布尔行完成一样。我现在已经将所有字段都转换为private,并使其中一些字段仅可由getter属性公开访问。当我创建结构的新“副本”时,使用我想要的新数据(如您所说),它似乎工作正常。但正如我所说的,无论哪种情况,颜色场都可以正常工作。我还想知道使用'ref'关键字是否也不正确?这似乎也会引起我的问题,即使rowComplete在字典中已更改,但在方法中的本地“node”参数中未更改