好的,我有List<SpecialTile>
名为SpecialTiles
,其中SpecialTile
是一个结构。 SpecialTile
结构的一个属性是一个名为Active
的公共布尔值,我正在尝试更改,但由于某种原因它不起作用。我不确定它是否相关,但列表由另一个类的实例拥有。这是我在调试器中运行它时的图片:
所以无论如何,我遇到了这个问题,因为最初我试图使用代码行
Mgen.SpecialTiles[ESV.editThis].Active = !Mgen.SpecialTiles[ESV.editThis].Active;
但它告诉我“Active”不是变量。正如您所看到的,它不会让我以这种方式修改价值:
所以我假设我必须通过方法修改值。但显然这也不起作用?
我是否遗漏了有关List变量的内容?即使它不应该修改该值,为什么调试器列出“Active”为false然后将其翻转为true?
谢谢!
答案 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,然后在屏幕上以两倍大小绘制它,但阵列中没有任何变化!
工作,但实际上,这些电话都没有立即发生。以上示例的工作方式如下:
总结:不要过度使用结构,或者很好地了解结构,在进行变异时要格外小心。