Public 结构变量没有改变
Public variable of struct is not changing
好的,我有一个名为 SpecialTiles
的 List<SpecialTile>
,其中 SpecialTile
是一个结构。 SpecialTile
结构的属性之一是一个名为 Active
的 public 布尔值,我正在尝试更改它,但由于某种原因它不起作用。我不确定它是否相关,但该列表归另一个 class 的实例所有。这是我通过调试器 运行 时的图片:
所以无论如何,我 运行 遇到了这个问题,因为最初我尝试使用代码行
Mgen.SpecialTiles[ESV.editThis].Active = !Mgen.SpecialTiles[ESV.editThis].Active;
但它告诉我“活跃”不是一个变量。如您所见,它不会让我以这种方式修改值:
所以我假设我必须通过一种方法修改值。但显然这也不起作用?
我是否遗漏了有关列表变量的内容?即使它不应该修改该值,为什么调试器会将“Active”列为 false 然后将其翻转回 true?
谢谢!
这是结构的问题。调用列表索引器 MGen.SpecialTiles[x]
returns 存储在列表中的结构的副本,因此您对该结构调用的任何方法都将对副本进行操作。由于副本是临时的,因此该方法所做的更改最终会被丢弃。
如果您将 SpecialData
更改为 class,这应该可以解决您的问题。
这个变量并不顽固。您 misunderstood/didnt 注意到 struct
很特别。
结构是按值处理的,而不是按引用处理的。
当你写:
foo.mystructList[5]
您指的是列表中的一项。但是因为那个 List 不包含对象 - 这个索引 return 是你 a copy.
考虑一下:
var temp = foo.mystructList[5]
temp.flip()
您现在希望 'flip()' 起作用吗?请记住,列表包含结构。当然,您不会认为它有效,因为您正在翻转副本。
现在回到你的案例:
foo.mystructList[5].flip()
同上!我只是消除了临时变量,但在内部,这是一样的。读取列表,return编辑副本,在副本上调用翻转。
此处:
foo.mystructList[5].prop = true
编译器拒绝'lefthand is not a variable',因为它知道左手是'a copy',很快就会消失。
此处:
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!
..但是如果它试图改变结构,它仍然会成功,但是在副本上。没有警告,因为它在所有情况下都是正确的 - 第一次看到时会感到惊讶。
举个有趣的例子,考虑 'chaining':
struct Rect {
....
public Rect twiceMe() {
this.SizeX *= 2;
this.SizeY *= 2;
return this;
}
}
foo.rectangles[5].twiceMe().draw();
在这里,twiceMe() returns 改变了 this
,所以我可以 "immediatelly" 在它上面调用 draw
。好像我即时将矩形乘以 2,然后以两倍大小将其绘制在屏幕上,但数组不会有任何变化!
有效,但实际上,none 这些电话确实是即时的。上面的例子是这样的:
- 从数组中读取第六项,return该项(自动复制到这里)
- 在那个副本上调用 twiceMe(),return "this" 从它(这里自动复制,太)
- 在原件的放大副本上调用绘图
总结一下:不要过度使用结构,也不要太了解它们,在改变它们时要格外小心。
好的,我有一个名为 SpecialTiles
的 List<SpecialTile>
,其中 SpecialTile
是一个结构。 SpecialTile
结构的属性之一是一个名为 Active
的 public 布尔值,我正在尝试更改它,但由于某种原因它不起作用。我不确定它是否相关,但该列表归另一个 class 的实例所有。这是我通过调试器 运行 时的图片:
所以无论如何,我 运行 遇到了这个问题,因为最初我尝试使用代码行
Mgen.SpecialTiles[ESV.editThis].Active = !Mgen.SpecialTiles[ESV.editThis].Active;
但它告诉我“活跃”不是一个变量。如您所见,它不会让我以这种方式修改值:
所以我假设我必须通过一种方法修改值。但显然这也不起作用?
我是否遗漏了有关列表变量的内容?即使它不应该修改该值,为什么调试器会将“Active”列为 false 然后将其翻转回 true?
谢谢!
这是结构的问题。调用列表索引器 MGen.SpecialTiles[x]
returns 存储在列表中的结构的副本,因此您对该结构调用的任何方法都将对副本进行操作。由于副本是临时的,因此该方法所做的更改最终会被丢弃。
如果您将 SpecialData
更改为 class,这应该可以解决您的问题。
这个变量并不顽固。您 misunderstood/didnt 注意到 struct
很特别。
结构是按值处理的,而不是按引用处理的。
当你写:
foo.mystructList[5]
您指的是列表中的一项。但是因为那个 List 不包含对象 - 这个索引 return 是你 a copy.
考虑一下:
var temp = foo.mystructList[5]
temp.flip()
您现在希望 'flip()' 起作用吗?请记住,列表包含结构。当然,您不会认为它有效,因为您正在翻转副本。
现在回到你的案例:
foo.mystructList[5].flip()
同上!我只是消除了临时变量,但在内部,这是一样的。读取列表,return编辑副本,在副本上调用翻转。
此处:
foo.mystructList[5].prop = true
编译器拒绝'lefthand is not a variable',因为它知道左手是'a copy',很快就会消失。
此处:
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!
..但是如果它试图改变结构,它仍然会成功,但是在副本上。没有警告,因为它在所有情况下都是正确的 - 第一次看到时会感到惊讶。
举个有趣的例子,考虑 'chaining':
struct Rect {
....
public Rect twiceMe() {
this.SizeX *= 2;
this.SizeY *= 2;
return this;
}
}
foo.rectangles[5].twiceMe().draw();
在这里,twiceMe() returns 改变了 this
,所以我可以 "immediatelly" 在它上面调用 draw
。好像我即时将矩形乘以 2,然后以两倍大小将其绘制在屏幕上,但数组不会有任何变化!
有效,但实际上,none 这些电话确实是即时的。上面的例子是这样的:
- 从数组中读取第六项,return该项(自动复制到这里)
- 在那个副本上调用 twiceMe(),return "this" 从它(这里自动复制,太)
- 在原件的放大副本上调用绘图
总结一下:不要过度使用结构,也不要太了解它们,在改变它们时要格外小心。