Andrew Brust (Microsoft Regional Director, INETA Speaker, co-lead of the NYCDotNetDev User Group) did me an enormous favor and finally cleared up my confusion about static/shared in VB.NET. I have asked a few C# gurus in the past who basically responded that VB wasn't a language and I should just C# (rather than answering my question). Sheesh.
I don't even remember if I used static variables in VB6[and previous versions]. VB's Static variables have nothing to do with C# (and other semi-colon languages) static variables.
In C#, "static" refers to class members that are associated with the class itself and not tied to a particular instance of the class. Therefore you don't need to instantiate the class to have access to the property or method. For example, you can call DateTime.Now without having to instantiate a DateTime object.
A "static" class is a class that contains nothing but static members.
Additionally, the static variables stay cached (since they are not dependent on a particular instance). So you can keep using them for the lifetime of your application, and they will retain their value. This is especially helpful in the middle tier, where any client that comes along and access the middle tier will have access to the same piece of data. Think of a web application. On the server, the application is running while different sessions start and end. If a user's actions cause a static datatable to be populated, the next user will (in most cases) get that datatable with that same data in it, rather than having to perform the same "populating" action.
VB.NET has the same thing as static. It's just called "Shared". Note the capital "S". It was given a completely new name because the name "Static" was already taken in the VB language.
VB's "Static" is a totally different beast. Static in VB only refers to variables. A Static variable is a variable that is local to a specific method (sub or function) or propert* in a class. The method must be a Shared method. Since the Shared method is not tied to an instance of it's class, the Static variable inside the method is able to retain its value from one caller to the next. So that variable is cached as well. But with lots of rules and lots of coding overhead. Arrgh, somehow I've still got this part wrong. Definitely the fact that the compiler told me “this static variable just be in a shared method“ has something to do with this. Bill McCarthy wrote a post about static variables in VB to make up for this part of my “lesson“.. Adding to my confusion is the documentation's explanation that Static variable is not in a Shared method, it will be tied to a particular instance of class. So that means it's not cached for all clients to get at, but it behaves more like a field of the class even though it's encapsulated in a method. It kind of makes sense to me, but still kind of doesn't, and I have to keep reminding myself not to take it personally. Bill is a true VB language guru and my confusion will probaby not make any sense to him. But I think I am representative of a lot of developers and I think I'm going to just stay away from VB Static and stick with the CLR. Anyway, back to our original programming...
And that's overhead which I trapped myself in when I accidentally used a Static variable in a VB solution. I had started with some C# sample code that used a static variable. When I tried to duplicate the static variable in VB (and using the same keyword - Static), I was told by the compiler that that variable had to be inside of a Shared method (even though that is not always the case). So I did as I was told and had to split my functionality out into a nested class (another possible hack that I found was the only way to get my particular code sample working) and go through all kinds of hoops to rebuild this code in VB.
The sad part of this lesson is that these bloated classes were my Query Notification middle tier demos that I have presented at a conference and a number of user group meetings as well as published in CoDe Magazine. And I have them in production code. Granted the samples totally work, but they are more complex than they need to be, harder to explain, harder to understand and make you type lots of unnecessary code. I have never seen any other VB code to do the middle tier Query Notification, so I was kind of on my own in building this stuff.
Until Andrew brought up this issue of my silly use of VB Static variables when I could have more simply used Shared, not one person has ever pointed out to me that I went the long way around with my solution. I just figured that this was one of those occasions where C# was just so much more efficient than VB (everyone's always telling me that this is the case), but in fact VB was just as efficient - had I used a Shared variable instead.
Of course, I still accept that C# has the super duper cool Anonymous Delegates and VB doesn't, but VB will be getting lots of Anonymous goo in VB9. That is something I'm looking forward to.
I have been doing .NET for over four years now and I never learned the static/shared/static thing properly or thoroughly. I understood Shared Methods. That was very clear. But the variables and the dual definitions really screwed me up.
And I have to assume if they confused me that much then there may be a few other VB.NET developers who moved from VB6 that are just as confused. So here I go again, writing about what a dope I was so that hopefully someone else will avoid public or even private dopiness in the future.
So, hopefully, I've finally got it right this time. If not, I'll be marking up this blog post, but I'll make it clear where the edits are.