I, for one, thoroughly enjoyed your rant. I've felt that way at times about one thing or another, and do understand where you are coming from. I felt that the MSDN documentation started off quite poor, but was improved steadily over time until it became, largely, a good reference. There are still glitches in it, though, and I don't think it will really get better.

I hadn't really thought about it, but what you were saying about T made sense. I understood 'of T' because the concept had been kicked around C++ for the STL for at least a decade before it showed up in VB. If you didn't have that background, then, what has become standard, nomenclature for generics would not make all that much sense.

Still, when I was starting in VB, a paper reference was a good tool. Now, there are so many options, and so much information, that I wouldn't care to waste the shelf space on a thorough .NET reference, so MSDN is the best solution. Yet it is still just a reference, and not a basic tutorial on the jargon that changed from VB6 to .NET. Every field and focus has jargon. VB6 wasn't better or worse, it was just different.

As for substance, I don't think this question was answered by anyone earlier:
Quote Originally Posted by treddie View Post
Problem is the contents of CopyOfLines ALSO gets cleared! Is there no way to break the connection of "CopyOfLines" to "Lines"? This seems so unnecessary. After all, if I say:
Code:
a=10
b=a
a=0
Then (b) will still = 10 while (a) = 0.

Why does vb.NET have to break such simple logic and turn it into a gargantuan issue
The answer is simply: Classes.

The major change between VB6 and .NET was the move to an Object Oriented (OO) model. Under true OO philosophy, everything is contained within a class or structure. True globals are not allowed. In fact, since the closest you can come to a true global in .NET is a variable declared as Public in a module, and a module is quietly turned into a class with all Shared members, you don't actually violate that rule in .NET, though it looks like you do. Of course, VB6 was quite different in this regard, though the syntax for globals was identical.

The issue with classes is that they can hold ANYTHING, and can be of any size at all. Would you like to have a class that holds an array of open database connections, each of which maintains a List of Datasets? You can do it (at least up to the number of connections you can hold open at any one time) in .NET. So what should happen when you have some MASSIVE class and you assign it to a different variable of the same type:
Code:
Dim A as New MassiveClass
Dim B as MassiveClass

B = A
If MassiveClass was just an integer, then B = A would copy the value of the integer from A into B. Is that what you would want to have happen with the horrid class I described above? Should B open all new connections and add in all new datasets? Perhaps the new datasets would be necessary, but the connections could be shared between the two objects. Perhaps A was at the limit for open DB connections, so if B even TRIED to open all new connections it would just fail, meaning B = A would result in B being Nothing, Invalid, or crashing the program.

That's just an example, though it touches on key points. What you are expecting in your question is called a deep copy. As long as your data types are simple little things like numbers, then a deep copy is obvious and intuitive. However, once you start adding classes, your classes can be of any size and behavior. A deep copy can't even be performed in these cases, since the compiler can't always know how to do the copying. Sometimes it can, but not always. Another example would be a class that contained a form that was shown to the user, and was supplied to the class as an argument to the constructor, or created new if none was supplied. Should a copy pass over the existing form such that the same form is shown by both classes, or should the compiler create a new form for the new class? The compiler can't know what is best, nor can it be expected to study the class and figure out whether or not it knows what is best.

By default, every OO language uses shallow copies, so that just addresses of objects are copied. This also limits the amount of stack space needed for functions that take objects as arguments. Whether you declare those arguments ByVal or ByRef, you are just getting a four byte address, not a copy of the whole object stuffed onto the stack. What that address actually IS will be different uner ByVal or ByRef, but in both cases you just get an address. To perform a deep copy, you have to tell the compiler how to do so for each object that you want to copy. In C++ that would mean a copy constructor that tells the compiler "when I am copying an object, create the copy in this fashion." .NET doesn't include copy constructors, so you need to add a method that performs the Copy for you. There is an interface that you can implement that gives you a stub of a Copy function, but whether you use the interface or not, you will still be responsible for directing how the compiler performs the copy.

And that's why A = B doesn't work the same for classes as it does for simple numbers.

As a last point, I would rather dispute your suggestion that only 19% of VB6 users moved to .NET. I used to love VB6, but as soon as I became marginally capable with .NET, I switched over and would never willingly go back. Lots of people on this forum hold the same view. While I also realize that there are several people who don't want to switch, I would say that 19% may have been true in 2002, but is totally false by now.