1

I am creating a game that must calculate differences in player stats (Blood Bowl for those curious) and have written a routine to do such. However I am worried that changing variables may change the objects, which I do not want.

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 is of custom type player - and has an integer property called ST (Strength)

ignoring the if statements, they are to do with the game rules, the line AttackerStrength = DefenderStength; possess my issue.

Will the new assignment of AttackerStrength propagate back and effect AttackerCell.PlayerOnCell.ST? If so, how do I stop this?

  • *"Will the new assignment of AttackerStrength propagate back and effect AttackerCell.PlayerOnCell.ST?"* Try it? – Cid Feb 13 '19 at 09:47
  • It could be an issue if dealing with reference types (see https://stackoverflow.com/questions/35395500/when-i-change-the-value-of-a-variable-which-is-a-copy-of-another-it-changes-the). But `int` is a value type - so nothing to worry about - the values are completely independent. – mjwills Feb 13 '19 at 09:50

2 Answers2

2

No, because in this scenario AttackerStrength is declared as a local variable; assigning to AttackerStrength only changes the local variable. However! This is actually a nuanced topic:

If the local variable is an object, then changes to the state of the object are propagated, as there is only one object; i.e.

SomeObject foo = PlayerOnCell.Foo;
// ...
foo.Strength = 42; // will be seen everywhere; only one object

But if the local variable is a struct, then this does not happen, as assigning to foo copies the value:

SomeStruct foo = PlayerOnCell.Foo;
// ...
foo.Strength = 42; // not propagated - foo is a copy

(this confusion, btw, is a good reason to avoid mutable structs - they are evil! structs are rare, and in that rare event when you create one, you should default to readonly struct).

Likewise, if you are using "ref returns" and "ref locals", then you can end up changing the remote state - but you can't do this accidentally, as it requires specific ref syntax and an up-to-date compiler:

ref int DefenderStrength = ref PlayerOnCell.ST;
// ...
DefenderStrength = 42; // this will have changed the state inside PlayerOnCell

This also applies to the SomeStruct scenario if using "ref returns" and "ref locals":

ref SomeStruct foo = ref PlayerOnCell.Foo;
// ...
foo.Strength = 42; // updates the value from PlayerOnCell

(at this point we're mixing multiple very advanced concepts, so it is very rare you'd need to know about this last scenario in real code; and if you are in that world, almost all confusion here can be avoided by saying that all struct should either be readonly struct (the default) or ref struct (if it absolutely must be mutable) - that guidance stops you triggering almost all traps)

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
0

It will not propagate back because it was assigned by value, not by reference.

Triti
  • 131
  • 1
  • 8