Default Instances are EVIL !
Fri, Jul 23 2004 17:27
Like some second rate Hollywood scream flick, the undead are rising from the ashes. Just when you thought they had driven a stake through the heart of the evil creatures from VB6, they resurrect them to haunt you, to mess with your code, to play terrible tricks on you and intellisense ….. be afraid, be scared…….. Default Instances want to come out to play !!!
VB.NET is re-introducing Default Instances. And there are some major problems with their proposed implementation …..
Problem 1: (loss of state)
Form1.Show is an example of a default instance. Why is it EVIL, you might ask. Well because it just won’t die. If you set it to Nothing, then check if it is nothing, it won’t be, as they are self re-incarnating. In VB6, the way they worked was basically like this:
Private m_Form1 As Form1
Friend Property Form1() As Form1
If m_Form1 Is Nothing Then
m_Form1 = New Form1
Set(ByVal Value As Form1)
m_Form1 = Value
So as you can see, they are basically self instantiating. In VB.NET however, there are problems with this kind of code for Forms. Unlike VB6, a Form in VB.NET cannot be shown again, once it is closed. Yes, that’s right, unfortunately the implementation of Windows.Forms.Form does not allow for graceful recovery after being closed. So rather than throw an exception if you try to re-show a form, the VB team added code to check if the form had been disposed, since when a Form is closed, it’s Dispose method is called.
So the code now becomes more like :
Friend Property Form1() As Form1
If m_Form1 Is Nothing OrElse m_Form1.IsDisposed Then
m_Form1 = New Form1
What this means is the form is no longer a data container. Instead it is just the UI instance, and data is not retrievable from the form after it is closed. Programmatically, this makes interaction with a default instance a very different model from VB6. You really need to look at Data Binding to an exterior object/data source. The form as a state container is gone.
Problem 2 : (not settable)
Another difference from the Vb6 implementation is you cannot set the default property to a given instance of a from . Instead, you can only set the default Instance to Nothing. As explained above, setting the default instance to nothing is actually pretty useless in VB.NET, because the instance is not stateful anyway. So the very times you would do this in VB6, there is no point in VB.NET.
Added to that, the removal of being able to set the default instance to a given instance, hinders effective communication between forms, that rely on a factory generated instance. Instead they must now communicate via tightly coupled passing of instances, or yet another global variable.
Exactly why this feature was removed is not clear to me. It may be because of the issues of not being able to re instate a given form they found this to be misleading as the default instance would only be maintained while the form is open.
Problem 3 : (interferes with shared members)
Default instances are by nature a Shared property that returns an instance. However because the Shared property has the same name as the Type, then instance methods are no longer distinguishable from Shared methods, at least not to the casual reader. So code like Form1.ConnectionString may be an instance member using the Default Instance Form1, or may be a Shared member in the type Form1. When reading the code you have no way of telling other than to look in class view or object browser.
Ironically, this muddying of the waters comes at the same time the VB team has proposed to break existing code, and not allow Shared methods to be accessed via an instance variable.
What can I say ?? Absolutely freaking unbelievable ;)
To sum up :
The above is just a high light of some of the problems the re-introduction of Default Instances brings with it. You should note, that these issues are on top of the issues Default Instances have always had. That is, these are *additional* problems with the implementation.
That’s not to say that Default Instances don’t have some use. They do. But the way it is being currently proposed, it raises more problems than they address.
Problems 1 & 2, I am going to attribute to the WinForms team, as that is the root of the problem.
Problem 3, is really the fault of the VB team (and probably marketing) They foolishly think by adding this they will somehow address the problems of the incompatibilities with the past. Well as problems 1 & 2 show, it just isn’t going to happen.
They could of course do this a lot better, a lot more like the .NET way of doing things. The Default Instance Form1 is actually My.Forms.Form1. So they could just simply leave it there, and have an Imports statement, Imports My.Forms. Then people can choose to have Default Instances such as Form1, or only accessible via My.Forms.Form1.
No, instead they currently seem to want to force this upon us all. Options are a good thing. Letting developers *choose* is a good thing. Forcing things on developers is a bad thing, and forcing the EVIL undead on developers is… well EVIL.
- WinForms team fix up your act !! (Mark Boulter get a blog !! )
- VB team, give us the option to have Imports My.Forms on or off, and base that default on whether the project is upgraded or not.
Balance evil with good J