First off, sorry for not being able to come up with a better title. I tried, though.
I have a class like this
public class GameBoard : ICloneable {
private bool _isCloned;
public ObservableCollection<BoardPosition> BoardPositions { get; set; }
public GameBoard() {
BoardPositions = new ObservableCollection<BoardPosition>();
//this.BoardPositions.CollectionChanged += BoardPositionsOnCollectionChanged;
}
private void BoardPositionsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs) {
// if this event is raised from the NEW object, [this] still points to the OLD object
}
public object Clone() {
//var gameBoard = (GameBoard)this.MemberwiseClone();
var gameBoard = new GameBoard {
// make it VERY clear this is just a clone
_isCloned = true,
// deep copy the list of BoardPositions
BoardPositions =
new ObservableCollection<BoardPosition>(this.BoardPositions.Select(p => p.Clone()).Cast<BoardPosition>())
};
gameBoard.BoardPositions.CollectionChanged += BoardPositionsOnCollectionChanged;
// why does the target of the event point to the old object?!?
return gameBoard;
}
}
public class BoardPosition : ICloneable {
public int[] Coordinates { get; set; }
public BoardPosition(int[] coordinates) {
Coordinates = coordinates;
}
public object Clone() {
return new BoardPosition(new int[]{this.Coordinates[0], this.Coordinates[1], this.Coordinates[2]});
}
}
which implements ICloneable. Inside the Clone method i deep-copy the ObservableCollection, and attach the CollectionChanged event handler.
Now the problem is, when the CollectionChanged event of the new, cloned object fires, [this] points to the OLD object that was cloned. This can easily be observed as _isCLoned is always false when the event is raised, even though it is set to true during cloning. Why is this, and what can i do about it? I want [this] to have a reference to the new, cloned object of course.
var gameBoard = new GameBoard();
gameBoard.BoardPositions.Add(new BoardPosition(new[] {1, 2, 3}));
var clonedBoard = (GameBoard)gameBoard.Clone();
clonedBoard.BoardPositions.Add(new BoardPosition(new[] { 2, 3, 4 }));