|
VB6 had class inheritance (interface inheritance), just not binary inheritance. Binary inheritance had to be accomplished by some minimal coding, but it was doable.
Oddly enough, as I found out when writing C# "OCXs" for use in legacy VB6 code, VB6 did have interfaces. If the class was named "Dog", the class interface was "_Dog" and the events interface was "__Dog". VB6 did all that for you "under the covers", which was both a blessing and a curse. COMInterop, in C#, with VB6 code, is a trip. A few "gotchas" not found when doing the same in VB.NET.
I meant architecture, in the context of the going from the limited OO in VB6's architecture to the essentially complete OO in .NET's architecture.
|
|
|
|
|
VB6 didn't have implementation inheritance. This is a rather massive omission. I wouldn't say it required "minimal coding" since you had to manually write a new implementation that delegated to an instance of the inherited type. I recall there are some add-ins that can actually do this for you. It also lacks Generics, but I think we can give it a pass on that since generics wasn't in many languages for some time after VB6's release. (Even though the lack of generics is the thing I find most infuriating as I frequently re-implement type-safe collection classes...).
the "interface" classes you see are the interfaces created by the VB compiler. Basically the interface was generated automatically and your actual concrete class would implement that interface. This get's even more interesting when you use Binary Compatibility and add new methods or Properties to a class- those methods and properties get added to a new interface (I forget the naming scheme) and your concrete class implements both that new interface as well as the old one. Pretty nifty, though sadly it didn't always work particularly well. Forms had similar magic; the Form was simply a class that actually inherited from the Form class, but when you create a Form, VB6 would also magically create a Global instance of that Form with the same name.
I mean I have fond memories of VB6 but I also use my benefit of Hindsight to realize that it was full of problems.
|
|
|
|
|
I agree with you for the most part. I always got tired of programming snobs who derided VB6 without really knowing what it was or how it worked. VB6 was safely usable for much more than it was given credit for.
When .NET first went into beta, I started working with it, and have been a .NET fan ever since. I like it much more than Java for rapid application development and for performance, and more than VB6 for sheer programming flexibility.
What you are describing with binary compatibility is that the VB6 compiler creates interface index numbers, using the most recent interface as the default interface. If you look at the type library definition for a VB6 DLL or OCX, you can see this, or you can look at the entries in the registry.
VB6 was not full of problems, but compared to .NET, it was lacking. VB6's biggest drawback is that it was designed for two very different audiences - the non-programmer who needed a good prototyping language with good performance, and the programmer. Unfortunately, too many lazy programmers wrote bad code, did not learn VB6 thoroughly, and blamed VB6, not themselves (not meaning you, of course).
I still have to maintain old legacy VB6 code, but I have not chosen to write new code in VB6 in a very long time.
|
|
|
|
|
As for VB6 being full of problems, perhaps I should qualify: For it's Era, it was a very good product. However, in the context of developing applications today, I'd say it's full of problems by virtue of being designed for the technologies of ~1998. So when I say "full of problems" I'm thinking more in terms of developing Applications that look and work like any Other win7 application. Off the top of my head I seem to recall having to hack in the resource manifest to get Visual Styles, Some whimsy and hacks to get Icons that support Alpha channels, and such. My most memorable experience was managing to actually get the Right-Click Explorer Menu in my own application, which involved crazy amounts of weak references, manual use of CoCreateInstance and QueryInterface, custom Typelibs for the shell interfaces, etc.
However, I also rewrote that functionality in C# later, too, and I found it to be a lot cleaner and easier. I can't say this is entirely because of the language and platform, because I'd like to think I simply got better as a programmer in the meantime. Perhaps ironically, I think it was easier to do because I didn't need to learn more; with the VB6 version I had to learn MIDL and the MIDL compiler, enough about IDL to define Interfaces, etc. with C# I could do that with attributes and C# interface definitions.
|
|
|
|
|
|
AspDotNetDev wrote: Barely. It didn't even have class inheritance or interfaces.
Not directly, no.
But with a bit of invention you could do it
Regards,
A
|
|
|
|
|
Now I'm curious. This indicates that it indeed supports interface inheritance (described here), and like you mention it does not directly support implementation inheritance.
I'd look into this inventive way to get implementation inheritance working, but I think won't since I don't plan to use VB6 ever again.
|
|
|
|
|
I didn't need it often - maybe a couple of times in a year. What I did was use an internal class with the same interface. A
|
|
|
|
|
|
That was the first letter of my first name -_-'
|
|
|
|
|
|
I worked in VB6 for years. I was firmly entrenched that I didn't need any other languages, because I could use all the APIs and add functionality if needed.
Using CreateThread() from VB6 was generally a very bad idea. You couldn't access anything from the VB runtime, since that was not re-entrant. The best you could get was an Out-Of-Process component as a "multiple thread" but I'm not sure if we can count that.
Now that I can look back on VB6, I can say that Classes and Object-Oriented support in VB6 was barely workable. When I think back to the things that took the most effort in VB6, I realize that almost all of that effort is either a result of features the language didn't have (such as emulating implementation inheritance by delegating to an aggregate and using implementation inheritance), or working around it's myriad fiobles (have fun implementing IEnumVariant!).
Compared to VB6, C# is (for me) like the difference between having to manually slaughter, gut, and butcher a Animal compared to simply having to cook a steak.
|
|
|
|
|
I agree that C#, and VB.NET, are much better than VB6. That is why I have not written new code in VB6 for years.
My approach, back in my VB6 days, was that if I had a performance bottleneck in my VB6 code that was not resource-related (disk I/O, RAM, etc.), then that code would get moved to C++ (or even C in some cases) to improve performance. But for Windows programming, VB6 was pretty much all that was needed. I wrote Windows services, COM+ servers, other middleware, as well as UI code with VB6. All worked well. Classes and OOP in VB6 was easily doable, for its day, so long as I took the time to know how things worked. I find OOP in C# and VB.NET is not only easier today, but has the additional functionality not available in VB6. Plus, I can write 64 bits apps, which I cannot in VB6.
Using CreateThread() in VB6 is not a bad idea, just one that requires a little knowledge. For example, I used a TLB for the thread API to bypass the runtime and go to OLE directly. The code I wrote for multithreaded VB6 apps was always stable and worked well. My code was adapted from some work Srideep Prasad did and posted on Planet Source Code back in the day.
VB6 was excellent for its day, did not deserve the reputation it had, and was the best Windows development language available then. But that was 12 years ago when .NET took its place.
|
|
|
|
|
Welcome to my world. We have an application that was converted from mainframe COBOL to netCobol, i.e. the worst .Net step-child ever thought up, then converted to C# a few years later. The Brainchild behind this endeavor felt it necessary to code this into the netCobol version.
toolStripStatusLabel1.Text = "Silly error message that by rights should be in a message box.";
Console.Beep();
This kind of thing exists 87 times and they're still in the new C# version. I figure if a message to the user is important enough to require a beep to get their attention, it should really be in a message box. Then again, the person coding this app also thought it would be a good idea to load the main form with 12,000+ lines of code, most of which is business logic. But what do I know, I only have an associates degree.
Comments from work:- "Why can't you just do it like everybody else?"
- "Well, we haven't had any complaints yet."
- "I just want to get it into production."
- "It only matters if it’s important to someone who matters."
|
|
|
|
|
I feel for you, I really do.
The one redeeming factor where I am is that I'm in the position of determining the new architecture, so a lot of detritus is firmly being shown the door.
PS. I knew some company must have been using one of the odd .NET COBOL variants.
It could be worse, I had to port some RPG to C years ago, and there is indeed an RPG .NET compiler. Look at the (Wikipedia[^] to see how bad things could be.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
Alan Kay.
|
|
|
|
|
Thanks. It's encouraging to know there are people in the position of being able to kill code silliness and then have the sense to do it.
As for RPG.NET, yuck. I think I'll avoid it as much as I do netCobol, a subject you realy don't want me to get started on.
Comments from work:- "Why can't you just do it like everybody else?"
- "Well, we haven't had any complaints yet."
- "I just want to get it into production."
- "It only matters if it’s important to someone who matters."
|
|
|
|
|
Perhaps they had to run lengthy jobs while they slept, and had it beep to wake them up in case anything went wrong?
|
|
|
|
|
|
I always thought that was what the keyboard auto-repeat beeps were for - to notify you that you've nodded off at your keyboard.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
Alan Kay.
|
|
|
|
|
A beep wouldn't wake you up unless you're a mosquito 
|
|
|
|
|
Especially not here, where PC speakers are disconnected by company policy.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
Alan Kay.
|
|
|
|
|
I'd wake up if an ant farted.
|
|
|
|
|
AspDotNetDev wrote: I'd wake up if an ant farted.
Because of the sound or because of the smell?
Author of Primary ROleplaying SysTem
How do I take my coffee? Black as midnight on a moonless night.
War doesn't determine who's right. War determines who's left.
|
|
|
|
|
Back in the day a beep was a good thing to have.
So what did you replace it with when you rewrote the vb6 code? 
|
|
|
|
|
There are two parts:
1. We now use a .config file to store these settings. Reading these is done during app startup. If errors occur, either (a) a message is shown to the user if the settings is required, or (b) an entry is made in a log if the entry is non-critical.
2. The original coding loaded the settings within a VB Form. I've migrated this to app startup code, so the errors (a) raise an exception so they can be reported back to the user in a more managed way.
The old app has the business logic entirely in VB forms, in the new version almost all business logic is in C# classes, the (WPF) forms have minimal code to set the data context for the form to an appropriate view model object.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
Alan Kay.
|
|
|
|
|