I am trying to add a few different members to a list, but when the list is added to it contains copies of only the last member added:
private PotentialSolution tryFirstTrack(PotentialSolution ps, List<PotentialSolution> possibleTracks)
{
for (Track trytrack = Track.Empty 1; trytrack < Track.MaxVal; trytrack )
{
if (validMove(ps.nextSide, trytrack))
{
ps.SetCell(trytrack);
possibleTracks.Add(ps);
}
}
return tryNextTrack(ps, possibleTracks);
}
The PotentialSolution
class looks like this:
public class PotentialSolution
{
public Track[,] board;
public Side nextSide;
public int h;
public int w;
static int cellsPerSide;
static bool testing;
static int minTracks;
.....
public void SetCell(Track t)
{
board[h, w] = t;
}
}
So we are trying to make several copies of the board
which only differ by which 'track' is placed in the current cell.
If I have a breakpoint at possibleTracks.Add(ps)
then I can see by inspecting ps
that the required cell contents is changing each time, as required.
But when the code reaches the next line (or the return statement), the cell content is the same in each member of the list (it's the last one that was added).
What I am doing wrong here? I have tried using an ArrayList and also a basic array instead, but get the same result. It's acting as though the board
member is decared as static, but it's not.
CodePudding user response:
You are adding references to the same object: ps
in possibleTracks.Add(ps)
You could add a constructor to PotentialSolution
duplicating the class:
public class PotentialSolution
{
public Track[,] board;
public Side nextSide;
public int h;
public int w;
static int cellsPerSide;
static bool testing;
static int minTracks;
//.....
public PotentialSolution()
{
}
public PotentialSolution(PotentialSolution ps)
{
board = ps.board;
nextSide = ps.nextSide;
h = ps.h;
w = ps.w;
}
//.....
Then use:
private PotentialSolution tryFirstTrack(PotentialSolution ps, List<PotentialSolution> possibleTracks)
{
for (Track trytrack = Track.Empty 1; trytrack < Track.MaxVal; trytrack )
{
if (validMove(ps.nextSide, trytrack))
{
ps.SetCell(trytrack);
possibleTracks.Add(new PotentialSolution(ps)); // duplicate object
}
}
return tryNextTrack(ps, possibleTracks);
}
This creates a new instance of the class each time it is added to the list.
CodePudding user response:
You always call SetCell
on the same ps
object you received as a parameter then add the same instance to the possibleTracks
list. The result is: possibleTrack
contains ps
n times and because it is the same instance you used in each cycle it will have the last change you applied via SetCell
call.
Not sure what you wanted to achieve but it looks you need a modified copy of ps
in each cycle for adding to possibleTrack
list. Making PotentialSolution
a struct
instead of class
could be enough? Structs are copied in such a way but may hit your performance if PotentialSolution
is big.
The board
member will still generate the same problem, because despite ps
will be copied but the board
inside it will contain same Track
references. The trick can be applied to Track
too, but the performance issues may raise more.
Just implement a Clone
on PotentialSolution
to have fully detached instances of it, then call ````SetCell``` on cloned instance and add that instance to the list.