Update: Changeables have become Freezables
Way back in December of 2003, I posted on Changeables in Avalon -- why they exist, what they're about, etc. Since that time, we received a good deal of both internal and external feedback (some of which was in response to that post -- thanks for the comments!). The general experience that people had was that the notion of a "use" of the Changeable, resulting in it's either being copied or not depending on another piece of runtime state, was too unpredictable. While that behavior was introduced for real reasons, the complexity of the "StatusOfNextUse" behavior overwhelmed many of the benefits, and resulted in frequent misuse.
As a result, we designed a number of simplifications to the model, and that is now publicly available as part of the "May 2005 Avalon Beta1 RC Release". Some noteworthy changes:
- The most cosmetic of the changes is simply the rename from Changeable to Freezable. This change makes the intent of the class more clear, and the names of the properties and methods are more in line with what it actually does.
- The most significant change is the complete removal of anything having to do with the notion of "use". So there is no "StatusOfNextUse" property.
- All assignments of Freezables made result in a reference to the Freezable being taken, and never a copy being made underneath the covers. That does change some of the semantics for some of the scenarios, but overwhelmingly simplifies things as well.
- As a result, if the developer wants to assign a value into a property, they can choose to Freeze() it themselves if they know no changes will occur to the object. This results in runtime savings of no longer needing to maintain event handlers waiting for something on the object to change.
- Another major change since the original post is the broad adoption of all properties of a Freezable being DependencyProperties. This allows all properties of Freezables (for instance, the color of a GradientStop in a GradientStopCollection in a LinearGradientBrush) to be animated in the same manner that all other properties in the system are. (Note that data binding can work on such properties as well, but there's currently no notion of an inherited data context, so the data context must be set directly on the Freezable that the binding directive occurs on.)
One thing that remains very much the same, though, is the notion of a single runtime type that represents objects that can both be mutable or frozen, and the ability to freeze a mutable object, and perform a deep copy on almost any object deriving from Freezable. The initial goals motivating Changeables have not altered with respect to these characteristics, and the "Freezable" semantics still does pervade many of the Avalon types.
We definitely believe that these changes result in a much more predictable system that's easier to use in the way the developer is intending to use it.