Wednesday, July 14, 2004
« My Expert C# Business Objects is officia... | Main | Middle-tier hosting: Enterprise Services... »

A customer asked me for a list of things VB can do that C# can't. "Can't" isn't meaningful of course, since C# can technically do anything, just like VB can technically do anything. Neither language can really do anything that the other can't, because both are bound to .NET itself.

But here's a list of things VB does easier or more directly than C#. And yes, I'm fully aware that there's a comparable list of things C# does easier than VB - but that wasn't the question I was asked :-)   I'm also fully aware that this is a partial list.

For the C# product team (if any of you read this), this could also act as my wish list for C#. If C# addressed even the top few issues here I think it would radically improve the language.

Also note that this is for .NET 1.x - things change in .NET 2.0 when VB gets edit-and-continue and the My functionality, and C# gets iterators and anonymous delegates.

Finally, on to the list:

  1. One key VB feature is that it eliminates an entire class of runtime error you get in case sensitive languages - where a method parameter and property in the same class have the same name but for case. These problems can only be found through runtime testing, not by the compiler. This is a stupid thing that is solved in VB by avoiding the archaic concept of case sensitivity.
  2. Handle multiple events in single method (superior separation of interface and implementation).
  3. WithEvents is a huge difference in general, since it dramatically simplifies (or even enables) several code generation scenarios.
  4. In VB you can actually tell the difference between inheriting from a base class and implementing an interface. In C# the syntax for both is identical, even though the semantic meaning is very different.
  5. Implement multiple interface items in a single method (superior separation of interface and implementation).
  6. Also, independent naming/scoping of methods that implement an interface method - C# interface implementation is comparable to the sucky way VB6 did it... (superior separation of interface and implementation).
  7. Multiple indexed properties (C# only allows a single indexed property).
  8. Optional parameters (important for Office integration, and general code cleanliness).
  9. Late binding (C# requires manual use of reflection).
  10. There are several COM interop features in VB that require much more work in C#. VB has the ComClass attribute and the CreateObject method for instance.
  11. The Cxxx() methods (such as CDate, CInt, CStr, etc) offer some serious benefits over Convert.xxx. Sometimes performance, but more often increased functionality that takes several lines of C# to achieve.
  12. The VB RTL also includes a bunch of complex financial functions for dealing with interest, etc. In C# you either write them by hand or buy a third-party library (because self-respecting C# devs won't use the VB RTL even if they have to pay for an alternative).
  13. The InputBox method is a simple way to get a string from the user without having to build a custom form.
  14. Sound a Beep in less than a page of code.

And please, no flames. I know C# has a comparable list, and I know I've missed some VB items as well. The point isn't oneupmanship, the point is being able to intelligently and dispassionately evaluate the areas where a given language provides benefit.

If C# adopted some of these ideas, that would be cool. If VB adopted some of C#'s better ideas that would be cool. If they remain separate, but relatively equal that's probably cool too.

Personally, I want to see some of the more advanced SEH features from VAX Basic incorporated into both VB and C#. The DEC guys really had it nailed back in the late 80's!

 


Wednesday, July 14, 2004 8:36:39 PM (Central Standard Time, UTC-06:00)
You missed Try... Catch ... When. This really improves exception handling
John Cavnar-Johnson
Thursday, July 15, 2004 6:14:12 AM (Central Standard Time, UTC-06:00)
Your number 1 coment about case sensitivity plus background compiler (a tool thing but vastly important) are the only things that prevent me from totally switching to C#. Everything else is small potatoes IMHO.
Daniel Moth
Thursday, July 15, 2004 11:33:11 AM (Central Standard Time, UTC-06:00)
Can you elaborate on a few of your list items? I haven't written hardly any VB.Net, so I'm not sure I understand items 2, 5, 6 and 11.

As for item 14, if anyone needs to know a simple way to sound a beep in C#:
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern bool Beep(int freq, int dur);

Beep(440, 100);

Not as easy as just calling Beep() in VB, but it isn't too bad to implement.
Monday, July 19, 2004 11:25:54 PM (Central Standard Time, UTC-06:00)
I can't speak to 5, 6, or 11, but for #2, I think he's talking about the ability to assign multiple events to a single sub procedure using the "Handles" keyword. Something like:

Private Sub ClickButton(sender as Object) Handles button1.click, checkbox1.click, label1.click
msgbox ("You just clicked " & sender.Text)
'do something else interesting here
End Sub

Brad Corbin
Tuesday, July 20, 2004 8:11:38 AM (Central Standard Time, UTC-06:00)
Number 5 is the same as number 2:

Private Sub Foo() Implements IBar.Work, IXyz.Neat, IAbc.Wow
End Sub

For #6, notice that, in the above code, the scope and name of the Foo method are entirely independant of the methods from the interfaces. It could be Public, Private, Protected, whatever. It could have any legal method name. As long as the signature matches IBar.Work (and the others) we're all set.

For #11, refer to the docs. Each Cxyz() method has its own features. Typically these methods can parse values that case the comparable Convert.xyz() or xyz.Parse() methods to fail. In a few cases, the Cxyz() methods compile down to more efficient IL than the corresponding Convert.xyz() method. For discussion on this last point, refer to http://www.panopticoncentral.net/.
Tuesday, July 20, 2004 11:12:46 AM (Central Standard Time, UTC-06:00)
C# is generally geared toward computer scientist, and is primarily designed for library construction. While performance differences are virtually small between the two languages, you cannot argue that VB performs betters, as VB tends to trades off performance (more checks, late binding, runtime overhead) for ease of use, while C# attempts to be a more productive, yet performance-oriented, alternative to C++. In particular, the VB runtime functions perform slower than the .NET counterparts (they do additional work) and ultimately call into the simpler framework counterparts. For example, see Mid and Len using Reflector. Microsoft generally uses C# for Windows development and a VB programmer would not be taken seriously.

VB tends to be better for component-oriented program (especially Office) and general developers, who may not have a computer science background.

The list was not constructed accurately, as the author demonstrates lack of experience with C#.

1) One key VB feature is that it eliminates an entire class of runtime error you get in case sensitive languages - where a method parameter and property in the same class have the same name but for case. These problems can only be found through runtime testing, not by the compiler. This is a stupid thing that is solved in VB by avoiding the archaic concept of case sensitivity.

Point #1 is not really an issue. Any potential errors are fairly rare. Properties are generally PascalCased and parameters are camelCased. Secondly, this is a feature prized in the C# community. Also, the intellisense corrects any casing issues, so it's not really an inconvenience.

You should also point out that the case-insensitivity of VB can result in the same type of ambiguities. A VB developer may attempt to call Count (a property) which is confused with count (a parameter). However, I believe the editor actually automatically corrects the casing.

2) Handle multiple events in single method (superior separation of interface and implementation).

Point #2 is also not unique to VB. The author clearly has not used C# event mechanism. C# can map events to the same method; this is the standard behavior in C#. The Handles keyword provides a declarative notation that does not provide any more expressiveness than the one-line of imperative code it replaces. This is primarily an ease of use alternative.

3) WithEvents is a huge difference in general, since it dramatically simplifies (or even enables) several code generation scenarios.

The author clearly does not understand the implementation of WithEvents; see Paul Vick's blog for details. WithEvents provides a declarative notation for a feature that can be written (and is internally written) in one line of code using AddHandler. This is primarily an ease of use alternative. When the variable is set, the VB calls AddHandler for each method associated with the variable, and RemoveHandler when the variable is changed.

4) In VB you can actually tell the difference between inheriting from a base class and implementing an interface. In C# the syntax for both is identical, even though the semantic meaning is very different.

This is a non-issue. In the framework, interfaces are preceded with the letter I.

5) Implement multiple interface items in a single method (superior separation of interface and implementation).

This is not unique to VB. Interface methods with the same name to the same implicit public method. What VB does add is the ability to map an interface method to an arbitrary method. This feature is dubious and can be imitated in C# with three lines of code by providing an explicit interface implementation and calling the arbitrary method.

6) Also, independent naming/scoping of methods that implement an interface method - C# interface implementation is comparable to the sucky way VB6 did it... (superior separation of interface and implementation).

I must point out that VB in 2003 does not allow derived classes to override an interface implemented in a base class. This is supported by C# and is used quite frequently in C#. VB Whidbey removes the restriction.

The separation of interface and implementation is not a valid point, since explicit interface implementation in C# provides the most general level of separation.

7) Multiple indexed properties (C# only allows a single indexed property).

This is a valid feature criticism. C# developers must define use methods. Let me point out in VB that the syntax for accessing indexed properties and methods calls is identical.

8) Optional parameters (important for Office integration, and general code cleanliness).

This is a valid feature criticism. C# developers must use operator overloading. The reasons for the omission of this feature is the poor versioning of optional parameters.

7) Late binding (C# requires manual use of reflection).

This is a valid feature criticism. Note reflection is at least 400 times slower than early binding. Secondly, calling reflection manually is not that cumbersome. Examples, here is how to call a method.

obj.GetType().GetMethod("Method").Invoke(obj, args);

8) There are several COM interop features in VB that require much more work in C#. VB has the ComClass attribute and the CreateObject method for instance.

The attribute is also available in C# and a framework CreateObject alternative is available.

9) The Cxxx() methods (such as CDate, CInt, CStr, etc) offer some serious benefits over Convert.xxx. Sometimes performance, but more often increased functionality that takes several lines of C# to achieve.

C# developers generally do not use the Convert class as it is quite redundant and more likely to perform words. C# supports direct casting syntax that map to IL instructions. I believe that the Convert class was originally introduced to support the needs of the VB team, not C# team.

10) The VB RTL also includes a bunch of complex financial functions for dealing with interest, etc. In C# you either write them by hand or buy a third-party library (because self-respecting C# devs won't use the VB RTL even if they have to pay for an alternative).

The runtime library is accessible to C# using Microsoft.VisualBasic.

11) The InputBox method is a simple way to get a string from the user without having to build a custom form.

True, a form is required ... but it does not provide a professional user interface.

12) Sound a Beep in less than a page of code.

Calling the Beep equivalent does not require a page of code, just 2 lines of code using PInvoke.
Beep requires a PInvoke declaration, and one line of code for each call to MessageBeep.

[DllImport("user32.dll")] public static extern bool MessageBeep( int beep );
MessageBeep(-1);

By the way, this is not a professional user interface.

Wednesday, July 21, 2004 11:24:58 AM (Central Standard Time, UTC-06:00)
All that said, I have a hard time understanding how people can use VB.NET to develop n-tier systems without the use of operator and conversion overloads.

RE: #3 The With statement would be handy for coding, but there are no real performance differences than simply declaring and using a local variable (which is what VB.NET does behind the scense)

RE: #4 Assuming you are using good coding techniques, I fail to see how this is helpful.

RE: #6 I'm not sure how it is handled in VB.NET, but in C#, if you declare that a method explicitely implements an interface's method, it is not available on the class' interface. That means you have to do a cast to see use it. However, if you declare it generically such that it matches the interface method's signature, it is available both through the interface's interface and the class' interface.

RE: #11
I can say from personal experience that I hardly ever use Convert.xxx. In C#, you would either use a direct case like:
Type myvar = (Type)myothervar;

or if you casting to a reference type:

Type myvar = myothervar as Type;

This second form does not appear to exist in VB.NET. Only if you explicitely wanted to Parse would you use a Parse method. If none of those options were available, then and only then would you use Convert.xxx.
Thomas
Friday, July 23, 2004 2:36:37 PM (Central Standard Time, UTC-06:00)
Don't forget IsNumeric() and IsDate() -- a couple of favorites of mine. I know that we're getting TryParse() methods on numerics and DateTime structures in .NET 2.0 which will do something similar, but until then ...
Saturday, July 24, 2004 3:31:24 PM (Central Standard Time, UTC-06:00)

For VB 2005, the best feature will be be the My namespace that gives easier access to the most common .Net library functions. This feature will not be available in C# 2005.
Monday, July 26, 2004 12:45:48 AM (Central Standard Time, UTC-06:00)
Here are two other things that VB.NET can do (compared to C#) :

1) Handling Name Collisions
---------------------------------------------------------------------------

The CLR supports two basic policies to use when the base and derived types have a method of the same name: hide-by-name and hide-by-signature. Every CLR method declaration indicates which policy to use via the presence or absence of the hidebysig metadata attribute on the derived type’s method. When one declares a method using hide-by-signature, only the base method with the same name and the same signature will be hidden. Any other same-named methods in the base will remain a visible part of the derived type’s contract. In contrast, when one declares a method using hide-by-name, the derived method hides all methods in the base type that have the same name, no matter what their signature may be.

Types defined in C++ use hide-by-name by default because that is the way the C++ language was originally defined. Types defined in C#, in contrast, always use hide-by-signature. Types defined in VB.Net can use either policy, based on whether the method uses the Overloads (hide-by-signature) or Shadows (hide-by-name) keyword.

Reference: Essential .NET (Don Box), CH 3 Type Basics, Types and Base Types PG 72

2) Restricutions when creating Value Types
---------------------------------------------------------------------------

The C# programming language imposes a restriction on value types, which is that value types cannot have default constructors.

Reference: Essential .NET (Don Box), CH 5 Instances, Objects and Values Compared PG 114-115

Wim De Ceuster
Friday, July 30, 2004 12:09:23 PM (Central Standard Time, UTC-06:00)
Actually I have an issue with point #1. I would say that case insensitivity of VB.NET is a reason to use C#. The problem is that the underlying .NET framework is case sensitive so the case of your method names and class variables are case senstive. This becomes apparent if you're doing reflection or remoting and use the wrong case, a very unintelligible exception is thrown. I'd rather be forced to deal with case sensitivity at the language level to prepare me to deal with the case sensitivity of the Framework.
Danh Dang
Tuesday, August 03, 2004 5:43:08 PM (Central Standard Time, UTC-06:00)
One note on your #7:

I've found that this C# restriction, of only one indexer per class, actually leads me to write more usable code. Why? Because instead of an indexed property, I end up with an instance of a collection class, which then has its own indexer. The syntax (Foo.Accounts[5]) is the same as for an indexed property, but the collection is more usable, because you can do foreach on a collection, or can pass it to any method that expects ICollection, or can CopyTo() it into an array, or whatever else. You can't do that with an indexed property.

(Now I'm just waiting for generics, so I don't have to write *so much* code to create that collection class.)

I suspect that the C# group decided not to allow multiple indexed properties for this very reason.
Tuesday, February 21, 2006 8:43:58 AM (Central Standard Time, UTC-06:00)
I notice many comments are attacking the initial post... he did say this wasnt a "oneupmanship" contest... it appears the "fanboys" out there just can help themselves!
Nick
Thursday, March 02, 2006 12:05:13 AM (Central Standard Time, UTC-06:00)
Intellisense is better in VB, see picture:

"Top 10 reasons VB.NET is better than C#"
http:// www.vbrad.com /article.aspx?id=65

As for the comment by Wesner Moise: "Microsoft generally uses C# for Windows development and a VB programmer would not be taken seriously."

From personal experience this is not true. If you knew the truth MS are still advertising for C and C++ developers. AND if oyu think I'm kidding then ask yourself why isn't office written in .NET???

MS spends more money on support than dev so VB developers are taken seriously due to its popularity. Anyway both languages conform to the CLS and translating between the two languages is childs play.

The reason for managed code is that its easier to code but this comes at a performance price.
Jez
Comments are closed.