I've often wondered how Microsoft convinced so many people that "you can do x without writing a single line of code!" was the test of a quality programming language. However they did it, they did it successfully with a number of people I've worked for. That's how I went from being a Java programmer to being a .NET programmer.
Since Microsoft ripped off many of the concepts in .NET from Java, most of the time I'm not bothered by my situation. I'd like to say I was still coding Java, but that's just my ego. You say StringBuffer, I say StringBuilder.
While .NET as a whole may not be totally useless and evil - especially if you're writing in C# - VB.NET is pretty awful. I've never worked with VB6, so maybe I'm spoiled. Programming in VB.NET is like trying to accomplish an important task with a stoned, poop-throwing monkey as your partner. It's amazing. You'd think C had never existed.
Keywords
Everything in VB.NET has to be explicit, or the compiler gets really upset. If you want to overload a method, it's not enough to just create two methods with the same name and different signatures. You need to use the Overloads keyword. Want to declare a new variable? You'll need the Dim keyword (also a pretty good description of VB.NET's syntax rules).
Not all of the keywords VB.NET reserves (read: half the English language) are unnecessary. The rest fall into two categories: those which are taken from C and other languages, and those that are nonsense.
Not a moment ago, I was trying to remember the syntax for calling the constructor of a superclass from the constructor of a subclass. Super.new()? No... This.super.new()? No. This.parent.new()? Nope.
The keyword used to access the superclass is MyBase. In hindsight, it makes perfect sense. The class calls itself Me, so of course its properties are going to be MySomething. Having remembered how to do things properly, I was able to call MyBase to initialize MyProperties and run MyApplication until it was time to press MyCloseButton and send the whole thing to MyGarbageCollector.
"Structures"
I've heard that in SmallTalk, there are no primitives, only objects. Every language I've ever used until VB.NET has had primitive types. If I needed to make a primitive type a little more flexible, I could use a wrapper class to give it the functionality of an object.
VB.NET has its own special way of dealing with primitive types. At first, it might look like you access its primitives through wrappers. But those are no wrappers! They're Structures (which is not the same as a struct).
As far as I can tell, a Structure is an object that acts like a primitive. You can use it without instantiating it, you can only reference its value, you deal with it using operators, not methods. So then why isn't it a primitive? I assume it's so that the Structure can be easily recognized by the .NET Virtual Machine (or Common Language Runtime, as Microsoft calls it). But is the 32-bit integer really such an inconsistently implemented type that we can't just reference it directly?
Even if you could discuss primitive types as primitive types, you'd still have VB.NET insanity to deal with. If I want to set the value of a char, I can't do that by using a number or a character in single quotes. I have to do this: Dim c as Char = "?"c.
White space
VB.NET can only figure out what you're doing based on how much white space you leave around it. Sure, there are no curly braces or semicolons for putting several thoughts on the same line. It's not just that. If I wanted to, say, concatenate two strings, I'd need to have a space between each and the ampersand that joins them. Even though the ampersand is a damned operator, VB.NET can't recognize that if there's one in the middle of a string of text it should interpret the stuff on either side as two separate expressions.
Operators
The operators VB.NET offers are kind of limited and arbitrary. You can't ++ something to increment it. There is no time-saving ternary operator - you have to go through the whole if...then...else...end if, using up at least five lines and denying you the ability to perform a test inline.
Operators in VB.NET don't mean what you might think they'd mean, either. & is for concatenation, not bitwise operations (is there even such a thing in .NET?) or conditional statements. Not equal is represented as <>. Lots of popular operators are replaced by keywords, like and, or, and mod.
Methods
It's not just that a method has to have a keyword in its declaration in order to know it's a method that bothers me. It's that I have to use two different goddamned keywords for method declarations, depending on whether or not they return a value. If your method returns something, it's a function. If not, it's a sub.
Conditions
Computer languages have a lot to do with formal logic, and anyone who's ever studied formal logic or even given it five seconds of thought can tell you that a true condition and (or plus) a false condition equals false. So if you were a computer programming language and someone told you to do something only if condition A and condition B were true, wouldn't you move on to the next thing if you realized one of them was false?
VB.NET, bless its little heart, likes to be thorough. If you have an if statement with two conditions, it's going to check both of them. Even if they're joined by and and the first is false. Even if they're joined by or and the first is true. This is a huge pain in the ass if you wanted to do something like
if not x is nothing and x.indexOf(y) > -1 then ...
That test is going to
blow up if
x is nothing (
null, for the rest of the world),
even though you check for that, because it always checks the second expression.
Casting
To cast something in VB.NET, you have to use an idiotic function called cType. There's also cInt, cDbl, and a host of specific functions for different data types. But for objects, it's cType. C# understands Superclass obj = (Subclass) otherObj. But apparently that was too straight-forward for VB.NET, so we use this archaic function that's doing god only knows what. Probably it's just running off and doing it the normal way somewhere where it won't confuse our little VB.NET programmer pea brains.
The whole thing makes me feel like I'm five and being told I have to do things the way some little Napoleon of a babysitter wants them done, "just because". Trying to understand VB.NET as a programmer is like trying to understand etiquette as a toddler. I get so fed up sometimes I just want to curl up on the couch with my blankie and watch Sponge Bob.