Home > .NET, Application Design, Visual Basic > Why the default form instance does more harm than good

Why the default form instance does more harm than good

First things first. The default form instance is a feature of VB.NET for versions 2.0 and up, applicable only to WinForms projects, and provides a forms management functionality that is in keeping with the code “feel” of VB6, the predecessor of VB.NET. Functionally, this feature allows for the programmer to use the name of a form to directly reference instance members on that form’s class (i.e. controls, properties). This feature made sense when working with forms in VB6

This of course flies in the face of object oriented design (and the .NET framework’s design patterns for that matter) which leaves the onus on the developer to be in control of his own object instances. In essence it introduces a non-OO principle into an OO language — and this is the starting point of my argument that in net sum, this is a harmful feature… at least in the way it is presented in the default WinForms Visual Studio template (I’ll clarify that later).

This is not to say that there are some benefits to including the feature. Here’s a few ways in which the default form instance has had a positive impact:

  • It is consistent with the RAD (Rapid Application Design) philosophy deep set into VB’s genetics. Face it, having a globally available reference to any form in your project without writing a single line of code will get you on to the ground running.
  • It allows for an easier transition of VB6 code to .NET, including the upgrade of projects. Most upgrade tools focus on the code syntax itself and do not attempt to treat design features, so I would imagine that the upgrade of VB6 form projects to .NET without the concept of default forms would be painful in this regard. In fact, we don’t need to imagine too much — just take a VB.NET project with heavy default form instance references and convert it to C#. You’ll get a lot of errors gently reminding you that a non-shared member of an object requires an instance of that object. In fact, this error should serve as a giant red flag that VB is doing something that is somewhat “unnatural” to .NET’s sensibilities.
  • It allows for VB6 developers to make the transition to .NET with a little less pain. Now, I know this is a list of positives but to me being coddled is not an effective way to learn something new.
  • As part of the Application Framework it provides a consistent and commonly utilized set of features that you do not need to cook up yourself. I’m thinking here that if you needed to replicate in code a globally available set of singleton form instances then you probably would not get the job done better. And if you would have done it with more bells and whistles there’s nothing stopping you from extending the existing feature, right?
  • And I suppose I should include the obvious benefit of allowing you to declare a form as the startup form for the project and have it magically appear without writing any code. This is one of those benefits that is radically under-appreciated. That said, there is nothing stopping you from allowing this one default instance without ever explicitly using it in code anywhere else. Pretty much we all do that with WinForms already.

Okay, so what are the parts I have a problem with?

  • Giving the illusion that you can get away with a single, shared instance is dangerous. For those starting out with VB and forms it is too easy a habit to get into but when scope creep suddenly causes you to need multiple instances you will not likely have the correct experience and knowledge to suddenly switch to an OO perspective. Too often in the forums I see people using default forms for no better reason than they found code somewhere that doe sit that way and there was no need to question it. On the bright side if they find themselves looking for a job that offers VB6 work then they will be well adapted, right? 🙂
  • It is the default setting for Winforms projects and is made super easy to find by accident because My.Forms namespace is implicitly imported. At the very least they should make this an opt in feature so the developer can choose what length of rope to hang himself by. In fact, for developers who are new to programming and chose VB.NET as their first language this is a lot like leaving razor blades in a baby’s crib — he’s bound to find it sooner rather than later but not know how to use it once in his chubby, drool-soaked hands.
  • It encourages developers to not learn a basic OO mindset of using constructors and to essentially “own your objects”.
  • Its too easy to break the default form instance model by inadvertently choosing to make your own constructor to a form. Let’s say you go to a VB forum to find out about how to pass a value from one form to another. A common response would be to advise that you do so through a constructor argument. The advice is given without knowing that you are already using the default form for references elsewhere in your project. The constructor code is copied and pasted (let’s be honest here) and voila! You now have a bunch of red squigglies telling you that reference to a non-shared member requires an instance of the object.
  • And speaking of breaking the model, guess what happens when you have a second thread that tries to call a default form’s member? Nope, you do not get a cross-thread violation. Rather than bother you with a nasty exception the “My” feature set will detect that there is no default form created for that thread yet and make a new one that exists only in that thread. Ouch! That would take some time to find through debugging, wouldn’t it? And if that were me I would make that my last project using default form instances.
  • Creating an application that has a mix of default form references and instances will cause endless problems when debugging issues. This is the most common scenario that arises in forums because there is typically an unawareness that an instantiated form cannot be accessed through the default form syntax. While experienced programmers would not make this mistake it is far too easy for the less experienced to copy code from the web and unwittingly blend styles. At the least it just seems intuitive (especially for VB6 devs) to use the form’s name when trying to access a member, so the ease of error in this regard is high. It does happen and it happens more than you might think.

Bottom line, when I weigh the pros and cons above I feel that the default forms feature in Application Framework does more harm than good. I know that one of the main objectives in Visual Basic is to provide a simple and easily learned style of programming, and in that regard I think default forms is a huge success. What I would have preferred is that the default Visual Studio template offer a “compromise” version of the feature. Instead of offering the form as a singleton (thus making the instance callable by merely using the class name) it should have an instance created as a the startup form and referenceable through the ApplicationContext.MainForm function. That way you get the benefit of getting started quickly by not needing to explicitly create your starting form (or build your own Sub Main to house the instance)… and you get the benefit of not being lured into poor coding practice.

That just makes sense to me. How about you?

Advertisements
  1. June 22, 2012 at 5:50 pm

    Lovely just what I was looking for. Thanks to the author for taking his clock time on this one.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: