首先,对于不能提出更好的标题感到遗憾。不过,我尝试过。当深度克隆对象时,事件处理程序的奇怪行为
我有这样
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]});
}
}
其实现ICloneable类。在Clone方法中,我深度复制ObservableCollection,并附加CollectionChanged事件处理程序。
现在的问题是,当新的克隆对象的CollectionChanged事件触发时,[this]指向克隆的旧对象。这很容易被观察到,因为在事件发生时_isCLoned始终是false,即使在克隆过程中它被设置为true。 这是为什么,我该怎么办?当然,我希望[这个]有一个对新克隆对象的引用。
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 }));
明确指出事件处理程序的好处!我没有想到这一点。 – 2013-02-28 08:04:21
为了解决这个问题,我ban my了几个小时。非常感谢! – lightxx 2013-02-28 08:07:08