Another mea culpa observed by André van Meulebrouck; when dealing with casting I am in error and not as consistent in defining and describing it as I perhaps should be – one of the many perils of proof-reading your own material! For example, on page 338 of Volume I, I incorrectly associate boxing with down-casting where it should be up-casting!
Let’s limit our scope of consideration to .NET Class Hierarchies – in this respect I mean the way in which object inheritance is depicted in the MSDN documentation. For example, the WPF FrameworkElement has the following inheritance hierarchy (in part – for the original click here)…
This could also be “visualised” as a simplistic (asexual) genealogical family tree where the “originator”, the .NET System.Object, is at the top of the stack. If you want to see the “complete” family tree for WPF and .NET 4.5 have a look at this StackOverflow question – WPF 4 and .NET 4.5 class hierarchy poster.
When up-casting from the FrameworkElement one regresses through the ancestors – you go “up the family tree” to some point that may or may not terminate with the originator – the Object. Conversely, when down-casting, you go down through the descendants of FrameworkElement.
The up-cast operator :> is “static” – the compiler will let you know when you’re writing your code if there’s an error in your casting logic. Of course, you can always cast up the inheritance hierarchy to an Object but you cannot, for example, try…
let b5 = form :> TextBox
In this case the compiler knows, at design-time, that there is an error in your casting logic – TextBox is not an ancestor of Form in its inheritance hierarchy and the statement will be shown with a red squiggly – however, form :> obj will always “work” since, for .NET, Object is always at the root of the family tree. Consequently, when up-casting with :>, as long as your code compiles you won’t get a run-time type exception.
For down-casting, André proposes the mnemonic: The downcast operator :?> is downcast because it is sad that it can’t know at compile time whether the cast will work! Fair enough – I guess this is based upon emoticons – a “language” I am unfamiliar with!