Why is there a default instance of every form in VB.Net but not in C#?

This was added back to the language in the version of VB.NET that came with VS2005. By popular demand, VB6 programmers had a hard time with seeing the difference between a type and a reference to an object of that type. Form1 vs frm in your snippet. There’s history for that, VB didn’t get classes until VB4 while forms go all the way back to VB1. This is otherwise quite crippling to the programmer’s mind, understanding that difference is very important to get a shot at writing effective object oriented code. A big part of the reason that C# doesn’t have this.

You can get this back in C# as well, albeit that it won’t be quite so clean because C# doesn’t allow adding properties and methods to the global namespace like VB.NET does. You can add a bit of glue to your form code, like this:

public partial class Form2 : Form {
    [ThreadStatic] private static Form2 instance;

    public Form2() {
        InitializeComponent();
        instance = this;
    }

    public static Form2 Instance {
        get {
            if (instance == null) {
                instance = new Form2();
                instance.FormClosed += delegate { instance = null; };
            }
            return instance;
        }
    }
}

You can now use Form2.Instance in your code, just like you could use Form2 in VB.NET. The code in the if statement of the property getter should be moved into its own private method to make it efficient, I left it this way for clarity.

Incidentally, the [ThreadStatic] attribute in that snippet is what has made many VB.NET programmers give up threading in utter despair. A problem when the abstraction is leaky. You are really better off not doing this at all.

Leave a Comment