8

I am maintaining an application that has both VB.NET and c# components. I thought these two languages differed only in syntax, but I have found a strange feature in VB.NET that is not present in C#.

In VB.NET, I have the following class:

Public Class bill_staff Inherits System.Windows.Forms.Form
    ....
End Class

If I want to use this class in C#, I do this:

using (var frm = new bill_staff())
    frm.ShowDialog();

However, in the VB.NET code, the class can be used like this:

bill_staff.ShowDialog();

ShowDialog is defined in the metadata like this:

Public Function ShowDialog() As System.Windows.Forms.DialogResult

So in VB.NET, it is possible to call an instance method on the class. As far as I can tell, this seems to implicitly create a new instance of the class, and then calls the method on that object. In C#, this is not possible - static methods must be called on the class, and instance methods must be called on objects.

I can't find any information about this on the Internet. What is the feature called, and is it good practice?

The project was initially converted from VB6 - is it some weird legacy feature?

Oliver
  • 11,297
  • 18
  • 71
  • 121
  • you would need to create a new instance of the class before calling ShowDialog() – Ric Nov 19 '13 at 16:37
  • @Ric You don't. It compiles and runs fine. – Oliver Nov 19 '13 at 16:38
  • well considering the Function is an instance method and not a class method (ie not a Shared function) I find this quite odd... is an object not being created elsewhere? – Ric Nov 19 '13 at 16:39
  • 5
    Yes that is legacy behavior. Classes did not show up in VB until v4, before that Form.Show was The way to show forms. So to make previous code compatible with the old way, it is still legal, but as I understand it, it comes with some overhead. Instancing is the better method. You see lots of novice code here doing it the old way which shows they dont quite understand OOP. – Ňɏssa Pøngjǣrdenlarp Nov 19 '13 at 16:39
  • wow I just gave that a go and you're right! well you learn something new everyday! – Ric Nov 19 '13 at 16:41
  • Similar questions http://stackoverflow.com/questions/10601503/access-form-property-with-instance-vb-net http://stackoverflow.com/questions/4698538/there-is-a-default-instance-of-form-in-vb-net-but-not-in-c-why – MarkJ Nov 20 '13 at 18:05

2 Answers2

11

Yes that is legacy behavior. Classes did not show up in VB until v4, before that Form1.Show was The Way to show forms. In order to keep previous code compatible (VB3 was also very popular), the old method was maintained.

It is still supported in .NET as a legal means to show forms. Initially, this was added to make it easy to migrate VB6 code to VB.NET. But is also there to make it easy to get something running in VB - MS refers to it as functionality at your fingertips and similar phrases.

Basically, it provides the tinkerer an easy way to program without understanding Objects and OOP. Imagine the questions we would have here if Form1.Show threw an error.

Explicit instancing is the better method because it is object oriented and makes it less likely your code will reference - or create - a new Form2 when you actually wanted to use an existing instance.

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
  • 1
    +1. The VB6 documentation explains it [here](http://msdn.microsoft.com/en-us/library/aa262343(v=vs.60).aspx). The VB.net documentation mentions it briefly [here](http://msdn.microsoft.com/en-us/library/vstudio/87y2hdsf.aspx) but doesn't explain why it exists (legacy code). It's explained in this [MSDN technical article on VB2005](http://msdn.microsoft.com/en-us/library/ms379610(v=vs.80).aspx#vbmy_topic3) under `My.Forms` – MarkJ Nov 20 '13 at 18:16
  • @Plutonix -- You're saying that manually instancing the form is better, because you think it comes with some overhead, but isn't wasting the instance that .NET creates for you in the background a waste in itself if you don't use it? Doing the same thing twice effectively... – Keith Jun 08 '15 at 19:32
  • 2
    NET doesnt create one in the background, VB does when you use the default instance method (`Form1.Show`). Nothing is wasted because `Dim frm As New Form1()` creates just one form instance. Using the default instance can cause many problems having to do with scope ... – Ňɏssa Pøngjǣrdenlarp Jun 08 '15 at 19:36
  • Ah, okay. I used to be a C++ programmer. I've been just using Form.Show() for awhile now since I realized quite early on that the form (or at least I thought) it was auto-created for me on load. I was aware of the issues of scope, I just worked carefully around them, mostly by setting everything to private and never using Form.myVariable unless I absolutely was sure I wanted to. Thanks. – Keith Jun 09 '15 at 12:21
  • 2
    @Keith, here is another, longer explanation of some of the issues with [default instances](http://stackoverflow.com/a/28290434/1070452) – Ňɏssa Pøngjǣrdenlarp Jun 09 '15 at 12:29
5

For forms, VB creates a default instance for you behind the scenes. e.g., the following VB:

Public Class bill_staff
    Inherits System.Windows.Forms.Form
End Class

class testclass
    sub testmethod()
        bill_staff.Show()
    end sub
end class

is equivalent to the following C#:

public class bill_staff : System.Windows.Forms.Form
{

    private static bill_staff _DefaultInstance;
    public static bill_staff DefaultInstance
    {
        get
        {
            if (_DefaultInstance == null)
                _DefaultInstance = new bill_staff();

            return _DefaultInstance;
        }
    }
}

internal class testclass
{
    public void testmethod()
    {
        bill_staff.DefaultInstance.Show();
    }
}

This only occurs in VB for forms (classes which inherit from System.Windows.Forms.Form). Personally, I think this is a terrible 'feature' of VB - it confuses the distinction between class and instance.

Dave Doknjas
  • 6,394
  • 1
  • 15
  • 28