struct的公共变量没有改变

时间:2015-06-29 23:12:40

标签: c# list debugging reference

好的,我有List<SpecialTile>名为SpecialTiles,其中SpecialTile是一个结构。 SpecialTile结构的一个属性是一个名为Active的公共布尔值,我正在尝试更改,但由于某种原因它不起作用。我不确定它是否相关,但列表由另一个类的实例拥有。这是我在调试器中运行它时的图片:

Impossible?

所以无论如何,我遇到了这个问题,因为最初我试图使用代码行

Mgen.SpecialTiles[ESV.editThis].Active = !Mgen.SpecialTiles[ESV.editThis].Active;

但它告诉我“Active”不是变量。正如您所看到的,它不会让我以这种方式修改价值:

Still Impossible?

所以我假设我必须通过方法修改值。但显然这也不起作用?

我是否遗漏了有关List变量的内容?即使它不应该修改该值,为什么调试器列出“Active”为false然后将其翻转为true?

谢谢!

2 个答案:

答案 0 :(得分:5)

这是结构的问题。调用列表索引器MGen.SpecialTiles[x]会返回存储在列表中的结构的副本,因此您在该结构上调用的任何方法都将在副本上运行。由于副本是临时的,因此该方法所做的更改最终会被丢弃。

如果您将SpecialData更改为某个类,则应解决您的问题。

答案 1 :(得分:4)

这个变量并不固执。你误解/没有注意到struct是特殊的。

结构由值处理,而不是通过引用处理。

当你写:

foo.mystructList[5]

您指的是列表的项目。但由于该List不包含对象 - 此索引会返回副本

考虑一下:

var temp = foo.mystructList[5]
temp.flip()

你现在期望&#39;翻转()&#39;上班?记住List包含结构。当然,你不会认为它起作用,因为你正在翻阅副本。

现在回到你的案例:

foo.mystructList[5].flip()

与上述相同!我刚刚删除了临时变量,但在内部,这是相同的。读取列表,返回复制,在副本上调用翻转。

下面:

foo.mystructList[5].prop = true

编译器拒绝“左手不是变量”,因为它知道左手是副本&#39;很快就会蒸发掉。

下面:

foo.mystructList[5].flip()

编译器无法警告您:您正在复制一个方法。会发生什么,取决于方法 - 如果它与结构很好地结合,它将起作用。例如:

var area = foo.rectangles[5].calculatearea();   // =x*y, OK!
foo.rectangles[5].validate();  // throw when x<0 || y<0, OK!
foo.rectangles[5].draw(); // call some UI rendere with x,y,sizeX,sizeY, OK!

..但如果它试图改变结构,仍将成功,但在副本上。没有任何警告,因为它在所有情况下都是正确的 - 只是第一次看到时才会感到惊讶。

有关一个有趣的例子,请考虑&#39;链接&#39;:

struct Rect {
    ....
    public Rect twiceMe() {
        this.SizeX *= 2;
        this.SizeY *= 2;
        return this;
    }
}

foo.rectangles[5].twiceMe().draw();

这里,两次Me()返回改变的this,所以我可以立即&#34;立即&#34;在上面拨打draw。看起来好像我将矩形乘以2,然后在屏幕上以两倍大小绘制它,但阵列中没有任何变化!

工作,但实际上,这些电话都没有立即发生。以上示例的工作方式如下:

  • 从数组中读取第六项,返回项目(自动复制
  • 在该副本上调用两次Me(),返回&#34;这个&#34;从它(自动复制
  • 在原件的放大复印件上调用绘图

总结:不要过度使用结构,或者很好地了解结构,在进行变异时要格外小心。