我正在创建一个必须计算玩家统计数据差异的游戏(对于那些好奇的人来说是“ Blood Bowl”),并且编写了例程来实现这一点。但是我担心更改变量可能会更改我不想要的对象。
MyPanel AttackerCell = Frm_Menu.GameBoard.SelectedCell;
MyPanel DefenderCell = this;
int AttackerStrength = AttackerCell.PlayerOnCell.ST;
int DefenderStrength = PlayerOnCell.ST;
if (DefenderStrength > AttackerStrength && AttackerCell.PlayerOnCell.Skills.Contains("Dauntless"))
{
Random Dice = new Random();
int DiceResult = Dice.Next(1, 7);
if (DiceResult + AttackerStrength < DefenderStrength)
{
AttackerStrength = DefenderStrength;
}
}
PlayerOnCell是自定义类型的播放器-并具有一个称为ST(强度)的整数属性
忽略if语句,它们与游戏规则有关,这行代码AttackerStrength = DefenderStength;掌握我的问题。
新分配的AttackerStrength会传播回来并影响AttackerCell.PlayerOnCell.ST吗?如果是这样,我该如何停止呢?
答案 0 :(得分:2)
否,因为在这种情况下AttackerStrength
被声明为局部变量;仅分配给AttackerStrength
会更改局部变量。然而!这实际上是一个细微的话题:
如果局部变量是一个对象,则将传播对对象的状态的更改,因为只有一个对象;即
SomeObject foo = PlayerOnCell.Foo;
// ...
foo.Strength = 42; // will be seen everywhere; only one object
但是如果本地变量是 struct ,则不会发生 ,因为将值分配给foo
复制 :
SomeStruct foo = PlayerOnCell.Foo;
// ...
foo.Strength = 42; // not propagated - foo is a copy
(顺便说一句,这是避免使用可变结构的好理由-它们是邪恶的!结构很少见,在这种情况下,当您创建一个结构时,应该默认使用readonly struct
)。
同样,如果您使用的是“ ref return”和“ ref locals”,那么您最终可能会更改远程状态-但您不能偶然这样做,因为它需要特定的ref
语法和最新的编译器:
ref int DefenderStrength = ref PlayerOnCell.ST;
// ...
DefenderStrength = 42; // this will have changed the state inside PlayerOnCell
如果使用“引用返回”和“引用本地”,这也适用于SomeStruct
方案:
ref SomeStruct foo = ref PlayerOnCell.Foo;
// ...
foo.Strength = 42; // updates the value from PlayerOnCell
(此时,我们正在混合多个非常高级的概念,因此非常非常罕见,您需要在真实代码中了解最后一种情况;如果您 are < / em>在这个世界上,可以通过说所有struct
应该是readonly struct
(默认值)或ref struct
(如果绝对必须可变)来避免这里的所有混乱-该指导会阻止您触发几乎所有陷阱)
答案 1 :(得分:0)
它不会传播回来,因为它是通过值而不是通过引用分配的。