Tuesday, August 24, 2010

Be careful of MemberwiseClone

If you have noticed, there is a protected method, MemberwiseClone, on Object. It is tempting to use it as it provides a quick way to do shallow copy, which is quite useful sometimes. But I fell into a trap yesterday and finally figured out the root during my walk today. :)
The problem comes from a combination of two factors:
1) MemberwiseClone: I am using it as a cheap way to copy Drag and Dropped content.
2) Parent property: One of the property of all Expression objects that I can copy, is the Parent property that points back to the containing object. This is because of the necessacity to quickly, and reliabilty, find out the parent for certain actions. These actions include Insert an Expression before another, and find out what is the Operator of the Logical expression to display a little "And" or "Or" before the sub expressions.
Long stories short: I drag and dropped a Binary expression "(a+b)" with the "b" being an EmptyExpression. Everything is fine, it seems. But when I drop a second Binary that is the same, problem shows. Because I did a MemberwiseClone on the first Binary, the "b" component of the first is pointing back at the "original" Binary, which is conveniently thrown away at this point. Now when the second Binary is dropped into the "b". "b" went back to the Parent, in this case thrown away, to update its property. Because the thrown away Parent is not show on the UI, it seems nothing is changed. Surprise!
But the worse things comes after: When the old Parent is updating, it dutifully put the "b"'s Parent to nothing, as it is useless now. If I drop another Expression into "b" (which is still shown on the screen), its Parent is empty, and crash happens when it tries to ask its parent to replace itself with the dropped Expression.
This is a twisted explaination. Hopefully I have sometime to draw a Visio to showcase the problem.

No comments: