Demand More From VB
I seem to hear that proponents of VB lament that the C# programmers are better paid, while there are no fundamental differences between the two languages, since they generate the same IL.
(The salary differences probably depend a lot more on the type of people who gravitate to the languages; C# programmers, many of which were former C++ programmers, are more likely to have better computer science education. A study, highlighting the different backgrounds, showed that the C# programmers found tended to find the .NET framework easier, while VB programmers, on average, tended to find it more difficult than VB6.)
VB even has a few convenient features that C# lacks. Reflection is much easier to use in VB, where any method called on a variable of type object uses reflection. Using OLE automation is much more convenient under VB. Try calling an method from the Word object model from C# which doesn't support default parameters. Check this simple example from MSDN for opening a file in Word contrasting VB with C#.
' Visual Basic
ThisApplication.Documents.Open("C:\Test\MyNewDocument.doc")
// C#
object missingValue = Type.Missing;
object fileName = "C:\\Test\\MyNewDocument.doc";
ThisApplication.Documents.Open(ref fileName, ref missingValue, ref missingValue,
ref missingValue, ref missingValue, ref missingValue, ref missingValue,
ref missingValue, ref missingValue, ref missingValue, ref missingValue,
ref missingValue, ref missingValue, ref missingValue, ref missingValue,
ref missingValue);
C#, however, does offer better access to the platform with constructs such as unsafe programming and unsigned data types and doesn't carry with it any extra runtime.
Unfortunately, I am always struck by some new limitations on VB, how it does not convey all of the power of the CLR, or doesn't always compile to the most efficient representation of code in IL as in C#, many times opting for unnecessary reflection or boxing. Reflection is at least 400 times slower than the optimal representation. There seems to be a direct correspondence between the CLR and C#, that doesn't exist in VB. You would think equivalent code from VB and C# generate the same IL, but this is often not true. It seems to me that VB team was more concern about converting legacy code and that the first version feels like a port.
Take this point on object to structure conversion. Why on earth does VB call Activator.CreateInstance to create a structure, when IL contains instructions for directly initing a structure at a huge performance gain? VB also has other random limitations that don't exist in other .NET languages like not being able to derived a class on an interface, if a base class already derives from the same interface.
Most of the VB runtime functions and keywords perform poorly against the framework, and it's not because of the existence of another layer. The conversions functions like CInt() perform boxing prior to converting. The poor performing IO Functions should be ignored in favor of framework equivalents. A notable difference between C# and VB is in the use of For Each in VB, which always construct a IEnumerator object at the beginning of the loop. In C#, it's possible to have an allocation-free foreach loop, because the compiler calls the enumerator methods directly.
VB programmers should demand a better performing language from the Microsoft with more support for available CLR features. Fortunately, things are looking better in Whidbey. The next version of VB is adding the following C# equivalents to the language for parity:
1) Continue, Using
2) Operator Overloading (including ^, \, Widening, Narrowing and Like)
3) Unsigned Types
Also, reflection, which VB makes much use of, is being complete rewritten for performance. A quick look at the SSCLI source code indicated that the original version of reflection was written for generality and not optimized at all. The improved performance means tools will run faster and that reflection will become a more attractive alternative style of invoking methods.
I didn't know about the fact that you can't have an interface in a derived class if the parent supports that interface, but I guess I'm not surprised. If you actually do it in C# it can cause some weird and unexpected problems, so I would imagine that the VB team opted in favor of simplicity and straightforwardness (if that's a word). That doesn't explain why they would do so much boxing and reflection though.
Posted by: Patrick Cauldwell | January 27, 2004 at 09:38 AM
Just thought I'd address a few of the points you bring up:
* The Activator.CreateInstance situation was an unfortunate oversight rather than a conscious design decision. During the long development of CLR version 1.0, there was a lot of churn in how structures were handled and what you could and couldn't do in IL. Sadly, it appears that this non-optimal code generation slipped through. As soon as we found it, though, we fixed it and the code generation will be optimal in Whidbey.
* Not allowing interface reimplmentation was a conscious design decision, stemming from the fact that allowing it means that a base class has no control over what a child class can do to its implementation (unlike, say, regular methods which can be declared as non-overridable). However, the fact that: a) C# allows it, and b) the class libraries make use of the capability, means that this will be allowed in Whidbey as well.
* I'm not sure what you mean when you say "CInt() perform[s] boxing prior to converting." CInt is an intrinsic operator that in most cases (except for converting from Object, String, Date and Decimal) is expressed as an IL instruction. Even in the exception cases, no boxing should be occuring. Can you clarify the situation you're seeing?
* I would also take issue that "most of the VB runtime functions and keywords perform poorly against the framework." There's no question that some of the runtime functions contain extra functionality that may make them seem slower than framework calls that have less functionality. As far as keywords go, I would definitely be interested in which ones perform poorly since most map directly down to the same IL that the other .NET languages use.
Posted by: Paul Vick | February 04, 2004 at 01:09 PM
Oh, one other question I forgot... Can you elaborate on "In C#, it's possible to have an allocation-free foreach loop, because the compiler calls the enumerator methods directly."? AFAIK, neither C# nor VB allow the target of a foreach to be the enumerator directly - both languages always call the GetEnumerator method to fetch the enumerator.
Posted by: Paul Vick | February 04, 2004 at 01:26 PM
C# supports allocation-free foreach loops using an optimization that bypasses.
If a class implements GetEnumerator(), C# will call the method directly WITHOUT casting the object to IEnumerable. The object does not need to implement IEnumerable at all. The enumerator returned need not be derivable from IEnumerator either. The enumerator that is returned can be a struct, in which case no allocation is performed.
If the enumerator implements methods, MoveNext() and Current(), then these methods are called directly. Current can return a typed object, again eliminating any boxing calls. The enumerator does
Some of the examples in my blog are weak, but I have seen a quite a number of examples on posts around web . Unfortunately, my memory is weak and I had to grab the easy fruit. I will update you on any additional cases that I remember.
I'll update my post with any corrections.
Posted by: Wesner Moise | February 04, 2004 at 02:12 PM
I found a lost link that referred to differences between IL in VB and C#: http://builder.com.com/5100-6373-1027686.html Lost in memory, this article served as the basis for my claim that VB and C# produced different IL.
It seems that the most common difference is the introduction of NOPs, so it is possible that there are no real differences between generated code.
Posted by: Wesner Moise | February 04, 2004 at 02:29 PM
The issue was the performance of CXxx functions was raised in http://www.dotnetextreme.com/articles/performance.asp. Since I am not a regular user of VB.NET, I took the author's assertions as valid.
Posted by: Wesner Moise | February 04, 2004 at 02:32 PM
It's funny because Dan Appleman predicted in one of his early .NET e-books* that this would happen (C# developers paid more because "C# is more complex"). Manager stupidity is always a safe bet.
* Visual Basic.NET or C# - Which to choose, pages 37+
Posted by: Jeff Atwood | February 19, 2004 at 10:19 AM