We did little subclassing, either from real objects or from interfaces. I think we would benefit from more. In the case of our TextBox, which we did subclass from TextBox, we could have been more aggressive and given it a better interface to the TextModel. Perhaps an event-driven interface would have been good, perhaps just something that better hides the difference between the TextModels view of things (ArrayList) and the TextBoxs (a big string, or an array of strings).
I suspect that we would have done well to create a special collection class for our lines. There are casts to strings sprinkled around in the code, and we could have avoided many of these, perhaps all of them. The need to downcast collection elements is a serious flaw in languages like C#, and its being addressed in future versions. C# will have templates, for example, which will make it easier to set up collections containing objects of known type.
At one point in the Undo saga, we tried to build one class as a subclass of another. To do this, we needed to override a couple of methods . The compiler didnt like the way we tried to do it, and after a couple of attempts, we just built to an Interface instead. In this case, it was probably a better design anyway, but its not good to have the design pushed around by ignorance of the language and its syntax. In a future project, I would try to use more of the language facilities sooner. This is a delicate balance, because we dont want to slow down and we dont want to insert gratuitous differences in the code. But at this point I feel that I know parts of the C# and .NET system pretty well and that there are untapped riches that I could use if only I knew a bit more about them.