|
Introduction
The intent of this article is to once and for all prove, by means of empirical evidence, that the MSIL code generated by the VB and C# compilers are not equal, particularly when dealing with non void methods and string value comparisons. In order to prove this point, a contrast will be made between the MSIL code produced by each compiler for two identical assemblies, one coded in VB, the other in C#, with possible explanations as to why the differences exist. Afterwards, the significance of this discrepancy will be briefly discussed along with some biased comments intended to flare up the VB vs. C# language wars.
Test Assemblies
The two assemblies used in the test are identical in all respects. However, here I only provide the code for the one and only type each assembly exposes, as well as the resulting MSIL code representing the only two methods the identical types expose. To verify that “other factors” are equal as well, such as optimization settings, feel free to download the code. Finally, both assemblies were coded and compiled using VS.NET 2003 (.NET 1.1 SP1) on a Windows XP SP2 machine. Moreover, the MSIL code was obtained using ildasm.exe (version 1.1.4322.573).
VB type ClassLibrary1.Class1:Public Class Class1
Public Sub New()
End Sub
Public Function foo1(ByVal test As Boolean) As Integer
Dim i As Integer
If (test) Then
i = 1
Else
i = 2
End If
Return i
End Function
Public Sub foo2(ByVal test As Boolean)
Dim s As String = Nothing
If s = String.Empty Then
End If
End Sub
End Class
C# type ClassLibrary1.Class1:public class Class1
{
public Class1()
{
}
public int foo1(bool test)
{
int i;
if(test)
i=1;
else
i=2;
return i;
}
public void foo2(bool test)
{
string s = null;
if(s == string.Empty){};
}
}
So now we have two identical types, the former written in VB and the latter written in C#. First, let’s compare the MSIL code each compiler produces for member foo1.
VB MSIL (foo1):.method public instance int32 foo1(bool test) cil managed
{
.maxstack 1
.locals init (int32 V_0,
int32 V_1)
IL_0000: ldarg.1
IL_0001: brfalse.s IL_0007
IL_0003: ldc.i4.1
IL_0004: stloc.1
IL_0005: br.s IL_0009
IL_0007: ldc.i4.2
IL_0008: stloc.1
IL_0009: ldloc.1
IL_000a: ret
}
C# MSIL (foo1):.method public hidebysig instance int32 foo1(bool test) cil managed
{
.maxstack 1
.locals init (int32 V_0)
IL_0000: ldarg.1
IL_0001: brfalse.s IL_0007
IL_0003: ldc.i4.1
IL_0004: stloc.0
IL_0005: br.s IL_0009
IL_0007: ldc.i4.2
IL_0008: stloc.0
IL_0009: ldloc.0
IL_000a: ret
}
At first glance, the MSIL code produced by both compilers looks identical. First, each version has the same number of MSIL code lines as the other. Second, both versions have identical .maxstack directives, that is, each method expects to use the same number of stack slots as the other. However, if you look at the third line of MSIL code, the .locals init directive, which is used to declare variables and assign initial values to them, a striking difference exists between both versions:
VB: .locals init (int32 V_0,int32 V_1)
C#: .locals init (int32 V_0)
Why is it that, despite the fact that method foo1 makes use of one, and only one, local variable (i), the VB MSIL code declares and initializes an extra variable, variable V_0, one which is never used? On the other hand, the C# MSIL code declares and initializes one, and only one, variable, which makes absolute sense for the obvious reasons already stated.
Now the question becomes, why the discrepancy, regardless of how significant or insignificant it may be. I’m no expert, especially when dealing with MSIL, yet I am almost 100% certain that the unused variable is there only because, unlike C#, VB allows a function’s code path to not return a value, and when this happens, the unused V_0 variable becomes used. In other words, in VB, you can have a function with a certain return type, yet if you do not explicitly return a value of that type, the compiler will return the type’s default value for you, hence, the existence of the mysterious V_0 variable. To prove my point, let’s comment out the last line of the VB version of the foo1 method, the line that explicitly returns the function’s value. Public Function foo1(ByVal test As Boolean) As Integer
Dim i As Integer
If (test) Then
i = 1
Else
i = 2
End If
End Function
After the above change is made and compiled, the resulting MSIL code looks like: .method public instance int32 foo1(bool test) cil managed
{
.maxstack 1
.locals init (int32 V_0,
int32 V_1)
IL_0000: ldarg.1
IL_0001: brfalse.s IL_0007
IL_0003: ldc.i4.1
IL_0004: stloc.1
IL_0005: br.s IL_0009
IL_0007: ldc.i4.2
IL_0008: stloc.1
IL_0009: ldloc.0
IL_000a: ret
}
The only difference between both versions of the VB foo1 MSIL code is in the second to last line. The first version, which explicitly returns a value, pushes variable V_1 onto the stack, via ldloc.1, since V_1 represents variable i, which in turn holds the value that is explicitly returned. Contrast that to the second version, which doesn’t explicitly return a value and, thereby, results in the compiler pushing variable V_0, which always holds the default value of the function’s return type, onto the stack by means of instruction ldloc.0.
So the moral of the story here is that for any non void method written in VB, the compiler will generate MSIL code that always declares and initializes an extra local variable of the same type as its containing function, a variable which may or may not be used, respectively depending on whether the function does not explicitly return a value. My personal opinion here is that, although the extra variable is insignificant with respect to its impact on performance and memory consumption, nonetheless the VB compiler should be smart enough to include the extra variable if, and only if, the member’s code path does not return a value. If it does, then the declaration and initialization of the extra variable is without question pointless.
Now, let’s move on and take a look at the MSIL code the VB and C# compilers generated for method foo2.
VB MSIL (foo2):.method public instance void foo2(bool test) cil managed
{
.maxstack 3
.locals init (string V_0)
IL_0000: ldnull
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: ldsfld string [mscorlib]System.String::Empty
IL_0008: ldc.i4.0
IL_0009: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.
CompilerServices.StringType::StrCmp(string,
string,
bool)
IL_000e: ldc.i4.0
IL_000f: bne.un.s IL_0011
IL_0011: ret
}
C# MSIL (foo2):.method public hidebysig instance void foo2(bool test) cil managed
{
.maxstack 2
.locals init (string V_0)
IL_0000: ldnull
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: ldsfld string [mscorlib]System.String::Empty
IL_0008: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_000d: pop
IL_000e: ret
}
Well, it’s obvious with just a quick glance of the two versions of MSIL code generated for method foo2 that differences do exist, moreover, much more obvious differences than was the case with foo1.
First, comparing the code size comments for each version, it’s clear that more MSIL code is involved with the VB version () than with the C# version ().
Second, the VB version expects and will use three stack slots (.maxstack 3), while the C# version expects and will use only two stack slots (.maxstack 2).
From there on, all remains equal until we reach line IL_0008, at which point both versions drastically diverge.
The C# version first pushes onto the stack the Boolean result of the call made to [mscorlib]System.String::op_Equality, which is the function C# uses to compare string values when using the == operator. Then, it immediately removes (pop) this same Boolean value from the stack right before returning execution to the caller. Although the last pop seems pointless, there’s really no choice in the matter because a method’s evaluation stack must be left empty before returning control to the caller, unless a value is to be returned, as is the case with non void methods.
On the other hand, the VB version first pushes onto the stack the value 0 (ldc.i4.0), which will subsequently be popped off the stack as an argument to the call made to Microsoft.VisualBasic.CompilerServices.StringType::StrCmp, which is the function VB uses to compare string values when using the = operator, the Integer result of which is pushed onto the stack. Once that’s done, instruction ldc.i4.0 is once again used to push the value 0 onto the stack so that it may be subsequently compared to the Integer result of StrComp. Then, by means of instruction bne.un.s IL_0011, the last two values that were pushed onto the stack, that is, the results of the calls made to StrCmp and ldc.i4.0, are popped off, compared, and if inequality results, execution transfers to instruction IL_0011, which seems redundant since instruction IL_0011 follows immediately regardless of whether or not the result is inequality, yet most likely is used in order to pop off the stack the last two values that still remain on it.
So once again the question becomes, why the discrepancy, regardless of how significant or insignificant it may be. Well, in this case, the answer is clear and simple. For backwards compatibility reasons, VB is forced to use StrCmp instead of String::op_Equality, the results of which are quite different, with the more drastic one being that StrCmp considers an empty string and a Null string equal, which is not the case with String::op_Equality, and, furthermore, this is most likely the main reason why the former is used instead of the latter. From a pure performance standpoint, String::op_Equality is superior to StrCmp, although the performance gains will manifest themselves only when an intense number of string comparisons are made, perhaps those made inside a tight loop. Furthermore, there is an easy workaround which will eliminate this problem in cases where maximum performance is a must, and that is to use String.Equals or op_Equality instead of the = operator when comparing string values. For example, changing the VB version of foo2 to: Public Sub foo2(ByVal test As Boolean)
Dim s As String = Nothing
If String.op_Equality(s, String.Empty) Then
End If
End Sub
results in the following MSIL code: .method public instance void foo2(bool test) cil managed
{
.maxstack 2
.locals init (string V_0)
IL_0000: ldnull
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: ldsfld string [mscorlib]System.String::Empty
IL_0008: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_000d: brfalse.s IL_000f
IL_000f: ret
}
Note that now both versions of the MSIL code are identical, except for the second to last instruction. The C# version simply pops off the stack the last value that remains on it, via the pop instruction, whereas the VB version pops off the last value on the stack, compares it to zero, and if equality exists, transfers control to instruction IL_000f, all via the brfalse.s L_000f instruction, which in this case seems to be redundant, since the original if statement block is empty and therefore the compiler should be smart enough to ignore it, although on the other hand, the compiler is also smart enough to know that under most, if not all, circumstances, an if statement block will not be empty and, therefore, probably figures why even bother trying to detect one.
Significance of Test Results
You probably have come to the conclusion after having read this article that I am a C# programmer who is trying to prove a point. Well, you’re half right. I’m certainly trying to prove a point, and the point is that, for reasons that have to do with the intrinsic nature of the VB language, how you use the language, backwards compatibility with legacy code, and logical assumptions that result in inaction, the VB compiler generates code that is almost as efficient as the C# compiler but does not generate code that is as a efficient as the C# compiler.
(Note: biased statements intended to promote VB vs. C# language wars are about to begin, so you may want to stop reading.)
Having said that, let me make it quite clear that I do all of my imperative coding in VB, ever since I got my first job after having obtained my BS in MIS. It’s an excellent language that, since version 4 and to a greater extent starting with version 7 (.NET), doesn’t restrict the programmer to a single programming paradigm the way C# does. Regarding the significance of the differences in MSIL code this article focused on, who on earth really cares besides programmers that despise (CG) VB? Certainly, the folks that pay us to code could care less about all the statements made in this article, and I assure you that if I were to try to sell the case that C# is “better” than VB based on what’s in this article to a CIO/CTO that knows his .NET, I would probably be fired for my complete lack of business judgment. Furthermore, go and show Jim, VP of finance, the MSIL code that’s included in this article and try to make the case that all of his department’s VB applications should all be rebuilt in C#, and I guarantee you will be the laughing stock of the season, although some C# folks around here, one in particular, are bold enough to try something like this.
Really, the one and only reason I’ve written this article is just to throw gasoline on the flames of the VB vs. C# wars. I’m sick and tired of hearing all the rhetoric about all .NET languages being equal, because that is just not the case, for VB is without question superior to C#. Furthermore, I also pity all the pathetic premises, ones that are so easily negated, that are used to support the absurd argument that C# is "better" than VB. Things like “it’s too wordy” or “too much bad VB code exists” just does not cut it. If you start a C# vs. VB debate here on CP or anywhere, please make sure to give me the link so that I can participate.
Please don't take all my trash talk seriously. I respect all of you guys. It's just that I have zero respect for the C# language. It's just another RAD tool, nothing more, nothing less, that's been fortunate enough to leverage off the experiences, good and bad, of various other languages, including VB, and, furthermore, doesn't have to worry about existing legacy code. My attitude will likely change the day MS Office is written completely in C#.
Final Thoughts
Finally, I'm fairly confident that most of the conclusions I've made regarding the comparison of MSIL code generation between the C# and VB compilers are true. However, like I already mentioned, I'm no expert, yet if you are and know something I don't or was able to detect errors on my part, please let me know.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 102 (Total in Forum: 102) (Refresh) | FirstPrevNext |
|
|
 |
|
|
This is a question thrown out only by VB developers. Could this be because many are not professional developers? Case in point where a business does care was one of my clients about to lose a 1.5 million dollar contract DUE TO PERFORMANCE. I isolated the issues and told the VB.NET developer what changes had to be done. HE REFUSED TO BELIEVE THESE CHANGES WOULD HAVE ANY IMPACT AND REFUSED TO REWRITE HIS CODE. Management finally told me to rewrite it and do it in C#. Results? I improved throughput by a factor of 15 (with his code in release and mine in debug) and we saved the contract for the customer. 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
In doing analysis for one of my clients I found a lot of poorly written VB code....mostly by lazy programmers not because of the language. But I found one program that was extremely well written. I ran IL Analysis on the code and found one section that did a LateBind call on a collection (of a type I cannot remember). I looked at the section of code highlighted...and it all appeared to be efficient. I finally had to do a ton of searching and line-by-line comparison to find out the issue.
The collection was created in the beginning of a method. Later on I believe she had an If statement to determine how to load the collection. Finally she had a For statement which did the load.
That was what it took to take really well written code and end up with really inefficient code. This was using the 2003 build of VS and it may have been fixed between now and then....but your analysis was very well done and destroys the myth that says "it all ends up the same IL code".
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I'm curious as to whether you explicitly set the build mode to Release to ensure optimal MSIL code generation? I haven't checked this out on my own yet, but I suspect that redundant information like the extra local variables generated by the VB compiler is culled in a Release build. I've seen that csc.exe produces smarter MSIL code in a Release build than in a Debug build, which is not very surprising, given that Release essentially allows optimizations.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Obviously this is an old thread, but I'd like to spice things back up.
Okay, a bit of background. My first "real" job was as a VB coder which I did for a little over a year. I'm now a devoted C# developer and I love the language. I far prefer C# to VB. That does not mean hate VB, too much *wink, but I find that C# is mostly a better language.
I have seen some horribly written applications the last several years, the worst of which were in VB6. Some poorly written VB7 apps were written by a VB6 programmer. I'm not naive enough to believe this to be the fault of VB. It was very obviously due to poor coding and design by the programmer. However, the pure nature of VB for RAD has taken to the mantra of convenience and, as such, has led to more lazy programming practices. VB requires more lines of code, oddly (as it is intended for RAD), as the syntax is more cumbersome to write code. Over several thousand lines of code a C# coder can get it done much faster (at least in .Net 2.0 with our code snippets...VB might have been a hair faster in 1.1 and I emphasize might). An anecdotal testament is one of our coders. He was a CAD and parametric modeling designer who is our adopted son in IT. We've taught him to program (in VB by the previous senior developer) and I've since converted him to C#. He loves it and swears it is much faster to code in as it takes less lines.
Yes, C# is slightly more efficient and a hair faster. I find that the biggest advantage is in the syntax and the philosophical enforcement in the language. Case sensitivity is a GOOD thing. Maybe my bias comes from learning to code in C++, but it enforces better programming practices. C# also makes you a more versatile developer as it is easier to identify with coding in other languages...so reading others' code and switching to other development platforms creates less of a cognitive dissonance.
The biggest reason people discount VB is the amount of poorly designed applications written in it. I find this is due to the fact that VB is an easier entry point for beginning programmers than other "hardcore" languages and therefore will naturally have more poor code written as a result, more so than the result of a poor language. On the same token, just because people have written killer applications in VB doesn't mean they were able to accomplish this as a result of the language. They were good developers. Sure, they found shortcuts and nifty tricks available in VB, and maybe VB only, that made everything hum. But they, being good developers, would have done the same in any language they've become efficient in developing in.
Personally, I feel the programming paradigm enforced in C# leads to better programming practices and less lines of code. You learn to code better in a language like C#, generally speaking (there are always exceptions). Just my 2 cents.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
There's a big mess over here[^] too.
Check it out, I'm curious to see where this leads to.
Edit: Come to think of it, I saw this (Giancarlo's) article a while ago too. Still don't have an opinion on which is a "better" language though.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
In first example, an extra local is generated for the VB.NET function. I think that is there because of the alternate return value syntax (vb legacy). i.e. instead of using return <expression>, one can use <function name>=<expression> as alternate syntax. However unlike return statement that exits the function, the alternate statement simply assigns the return value to its placeholder. This value will be picked up as a return value whenever there are no explicite return paths (using return statement).
Now, as far as language comparison goes, I think its a subjective judgment. As far as I am concerned, I am a vb guy and IMO c# sucks simply because of case sensitivity. Frankly speaking, I don't see any reason why any morden language should be case sensitive unless for legacy reasons (which exactly is the case for c# - its case sensetive not because its a good thing (rather its a bad thing, do human mind really care about case while naming entities? Is sam differen from Sam?) but because it makes migration from java, c, c++ simpler.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Few more things...
1) In VB.NEt, developers have to make sure to set Option Explicit and Option Strict whi;e C# is case senstive anyways and you can't use a var before declaring and initializing it.
2) Case Statements in VB.NEt suxz!! In C#, developers have tp use "break;" which is a good thing. Also "goto", "jumps", "goto case" are other valid options.
3) In VB.Net u've to use newline continuation character & _ which is really annoying, in C#, no need to use anything.
4) VB.NET array is a descendant of the System.Array of the .NET Runtime which by definition has a fixed size on creation. The ReDim Preserve statement creates a new array - and the elements of the old array get copied into the new one. As this happens under VB.NET, it becomes performance killer.
5) C# uses PInvokewhich allows you to call functions and have data types be marshaled correctly which is much better than VB.NEt's "Declare " to call Windows API.
6) C#.Net permits you to write unmanaged code.
7) In C#, you can declare an object as "volatile" so it can be modified asynchronously.
8) VB.Net allows for a lot of implicit casting while C# requires casts to be explicit (Thank God!!)
9) When computing for checksum or hash on a class, the behavior of C# of not checking arithmatic overflow is reaaly helpful and then it provides "checked" and "unchecked" keywords.
MY FAV ONE
10) C#.Net is ECMA standardized and believe it or not, this is a HUGE difference to consider.VB.Net is still not standardized (and probably will never be ) so it lacks the cross-platform & vendor-support possibilities that a language like C++, C#, SQL92 offers. Therefore, C# IS a better choice over VB.Net
Hmmmmmmm, I think this much is good enough for now.
Cheers,
Neel
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Misty_Blue wrote: "In VB.NEt, developers have to make sure to set Option Explicit and Option Strict whi;e C# is case senstive anyways and you can't use a var before declaring and initializing it."
First of all, I think it's fantastic that a single language can be used as both a loosely typed and strongly typed language, and that it can be controlled at the file level. Furthemore, I also believe it's powerful that a single language gives you the ability to declare or not declare your variables before using them, and that it can be controlled at the file level. All the more power to the developer. I myself have no use for these features, except when I have to interact heavily with COM, in which cases late binding is sometimes useful, however, that doesn't mean someone else doesn't have a need for them. The options are there for the programmer to decide when and how to use them, if ever, and to me that's powerful Finally, I don't see what case sensitivity has to do with either feature.
Misty_Blue wrote: "2) Case Statements in VB.NEt suxz!! In C#, developers have tp use "break;" which is a good thing. Also "goto", "jumps", "goto case" are other valid options."
Are you kidding me? The VB Select Case statement is much more powerful than C#'s switch! You can specify a list of values, a range of values, or even both, or you can test using relational operators, etc... How do you do this in C#:
Case 1 To 4, 7 To 9, 11, 13, Is > MaxNumber
Well, you can't! At the most you can do something like:
case 9: case 11: case 13:
Or you have to "goto" the block of another case label. Sucks! In the end for complex relational operations you have to use the if statement, although there's nothing wrong with that, but to say that C#'s switch is more powerful is completely false. I do think it's cool that you can jump from one case block to another, but I think it sucks that you have to explicitly break out of one. I know there's no such thing as fallthrough as in C++ but couldn't this have been done without forcing an explicit break ?
Misty_Blue wrote: "3) In VB.Net u've to use newline continuation character & _ which is really annoying, in C#, no need to use anything."
Oh please First of all, line continuation is acheived with just the underscore and not the ampersand. Second, I would rather have to use the line continuation character on the few occassions that a code line is too long for a single line rather than have to type in a semicolon for every single line of code I write
Misty_Blue wrote: "4) VB.NET array is a descendant of the System.Array of the .NET Runtime which by definition has a fixed size on creation. The ReDim Preserve statement creates a new array - and the elements of the old array get copied into the new one. As this happens under VB.NET, it becomes performance killer."
First of all C#'s array also derives from System.Array, so they're one in the same with VB's. Second, ReDim Preserve is just a VB specific way of calling Array.CopyTo, which is what you would do if you want to increase the size of an array yet keep its current values, in the end you still have to create another one. Regardless of how you do it, yes I know it's a performance killer.
Misty_Blue wrote: "5) C# uses PInvokewhich allows you to call functions and have data types be marshaled correctly which is much better than VB.NEt's "Declare " to call Windows API."
So does VB! Sure you have the option to use Declare, in addition to DLLImport, but in the end all Declare statements are replaced with DLLImport. Once again, it's all about options .
Misty_Blue wrote: "6) C#.Net permits you to write unmanaged code."
So :-> Besides, I already told you that C#'s pointer is a poor excuse of one, and that if for some bizarre reason you need to use pointers, then you should be coding in C++. I also told you to give me a specific example of doing something with C# pointers that I cannot do in VB by using the System.Runtime.InteropServices.Marshal class.
Misty_Blue wrote: "7) In C#, you can declare an object as "volatile" so it can be modified asynchronously."
what can I say other than I will do my locking explicitly.
Misty_Blue wrote: "8) VB.Net allows for a lot of implicit casting while C# requires casts to be explicit (Thank God!!)"
No doubt, but it ALSO can funtion in explicit mode as well (option strict on baby It's all about options!
Misty_Blue wrote: "9) When computing for checksum or hash on a class, the behavior of C# of not checking arithmatic overflow is reaaly helpful and then it provides "checked" and "unchecked" keywords."
VB also allows you to disable overflow. No we don't have checked and unchecked, but I don't care .
Misty_Blue wrote: "10) C#.Net is ECMA standardized and believe it or not, this is a HUGE difference to consider.VB.Net is still not standardized (and probably will never be :sigh so it lacks the cross-platform & vendor-support possibilities that a language like C++, C#, SQL92 offers. Therefore, C# IS a better choice over VB.Net"
True, perhaps it's not standardized but it's making its weight felt. Ever heard of MonoBASIC?
Are you still standing ?
Take care dude!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Of course I'm still standing!! r ya kiddin me??
It all boiling down to "OPINIONS" just as i predicted. I mean u'r saying tht "that a single language can be used as both a loosely typed and strongly typed language" which is so funny!! 
It's like VB.Net allows you to do all the mistakes in the world. However, if youw ant, you can stop doing those mistakes. It's extremely stupid!! loolz
All those things you replied to are in the same fashion. Ultimately i'm just hoping that people would get my point that it is bogus to say one language is better than other when we're talking about C# and VB.Net and i wish that unlike some people who trash VB.NEt, you should stop trashing C#.Net 'cuz it's really pointless. Anyways, good luck =
Neel.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Sorry man but very weak counter, come on dude, you can do better, after all you started this and all the other threads I didn't drag you into anyone of them.
Misty_Blue: "i wish that unlike some people who trash VB.NEt, you should stop trashing C#.Net 'cuz it's really pointless"
Dude I don't understand why you like to tag on the ".NET" to C#. I myself can't stand the fact that VB.NET wasn't just simply called VB7 .
Well, I give up, you win! You may still be standing, but you've tired the hell out of me .
later
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hehehehe well, i wasn't discussing to "win". Besides, It's not even that i "hate" VB.net (or VB7 ) I just wanted to give the real answer that there is no such thing as "best/better language" in .net (i mean at least if we are comparing c#.net and vb.net)
and no i'm not tired of you. It was indeed interesting to brush up my knowledge of VB.Net (/VB7 )
Keep up your good work and keep posting articles.
Cheers,
Neel.
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
Coming at this from someone who uses both languages, and has used VB since 1.0...
Giancarlo Aguilera wrote: First of all, I think it's fantastic that a single language can be used as both a loosely typed and strongly typed language, and that it can be controlled at the file level. Furthemore, I also believe it's powerful that a single language gives you the ability to declare or not declare your variables before using them, and that it can be controlled at the file level.
Actually, I see this as one of VB's greatest weaknesses, and a reason why it isn't being taken seriously by many non-VB developers. When discussing a function or subroutine out of context, or at a formalized code review, you can't see how these options are declared at a file level, and so information that you need to know if the implementation is correct or not isn't there.
Option Explicit should not be supported in VB.NET. It was a mistake in VB 6, and it was a mistake in all previous versions, but in VB.NET (in particular) it should have been dropped outright.
Late binding is the only marginally acceptable use, and Microsoft could easily introduce a keyword or operator to support late binding.
The issue with Option Explicit off is it causes numerous hard to track bugs in an application of any moderate complexity, and it makes it impossible to deal with a function out of context (at a peer review, etc.).
Sub DoSomething() Offset = 0 Do While Not Done Offset = Offset + 1 Done = True End While End Sub
Is Offset class local? Is it sub local? Is it global (in VB6-)?
Does the line incrementing it set it to 1, or 01? If the loop ran multiple times, would it increment normally or would it end up being 01111111111?
You can't tell any of this from looking at the sub in isolation, and that is a barrier to communicating with other developers. It is also a barrier to effectively catching problems before code ships, which is traditionally what earned VB it's low reputation among other programmers.
Giancarlo Aguilera wrote: Are you kidding me? The VB Select Case statement is much more powerful than C#'s switch! You can specify a list of values, a range of values, or even both, or you can test using relational operators, etc... How do you do this in C#:
The C# approach lends itself well to things like interpreters, while the VB approach lends itself to certain varieties of data validation. Generally speaking, break is one of the statements in C++ and C# that causes the most odd, untrackable bugs (because people forget to use it a lot).
Both approaches have merits in different situations. Personally, I dislike break and think it should be removed from the C# language as well. Break doesn't get you anything a function wouldn't, and the function makes your intent crystal clear.
But then I think C# and VB.NET both should get inner functions and inner subs in order to promote clear, readable code -- so what do I know...
Giancarlo Aguilera wrote: Oh please ! First of all, line continuation is acheived with just the underscore and not the ampersand. Second, I would rather have to use the line continuation character on the few occassions that a code line is too long for a single line rather than have to type in a semicolon for every single line of code I write .
VB needs an equivalent of /* ... */ comments, which is where this complaint usually originates: void Func( int param1, // This parameter is for (blah) int param2 // This paramerter is for (blah) ) {..}
In VB.NET, you can't do anything equivalent: Sub Func( _ param1 As Integer, _ 'This won't compile with a comment here param2 As Integer _ 'This won't compile with a comment here )
If you look at were continuations are useful, it's almost always a sub/function declaration or an expression. If you allowed ( to auto continue until there was a matching ), without continuation characters, you could also address both complaints. But that won't happen anytime soon.
Giancarlo Aguilera wrote: First of all C#'s array also derives from System.Array, so they're one in the same with VB's. Second, ReDim Preserve is just a VB specific way of calling Array.CopyTo, which is what you would do if you want to increase the size of an array yet keep its current values, in the end you still have to create another one. Regardless of how you do it, yes I know it's a performance killer.
If you're talking like a game loop doing pixel manipulation or the like, in a C# unsafe block, it's possible to use a native array. It still doesn't perform as well as the equivalent C++ code, and it requires the full trust profile (which can be annoying) since it uses unsafe, but it can be done.
Giancarlo Aguilera wrote: 5) C# uses PInvokewhich allows you to call functions and have data types be marshaled correctly which is much better than VB.NEt's "Declare " to call Windows API."
So does VB! Sure you have the option to use Declare, in addition to DLLImport, but in the end all Declare statements are replaced with DLLImport. Once again, it's all about options .
Declare should generate a deprecated warning, in fact (it doesn't, but it should), because it's actually intended to be an aid in porting old code, versus something for new use. You open any VB 6 code that does anything with Windows, and Declare is the first line you'll see. There had to be a migration path, but they should inform you its a migration path and steer you in the right direction.
Giancarlo Aguilera wrote: "8) VB.Net allows for a lot of implicit casting while C# requires casts to be explicit (Thank God!!)"
No doubt, but it ALSO can funtion in explicit mode as well (option strict on baby ) It's all about options!
Option Strict is another one that should be locked on. Most programming shops I've worked at the last 10 years have required it to be on for all code. It's another one that was originally intended to ease migration from GW/Q BASIC that has served its purpose and should be out of there.
To support late binding, there should be a specific language pseudo-type or a modifier for System.Object: Dim A As LateBound System.Object
Giancarlo Aguilera wrote: Misty_Blue wrote: "9) When computing for checksum or hash on a class, the behavior of C# of not checking arithmatic overflow is reaaly helpful and then it provides "checked" and "unchecked" keywords."
VB also allows you to disable overflow. No we don't have checked and unchecked, but I don't care
Checked and unchecked are necessary, in rare cases, for performance.
In the case of the stated applications, though, I would typically use the C++ implementation of checksums or hashes in System.Security.Cryptography; even with unchecked, running in an unsafe block, you're unlikely to beat the implementations there for performance.
Microsoft omitted anything from VB.NET that is intended for use by low-level processes, where performance is typically critical. In C#, they put these capabilities in; in C++, they were standard. Any time you get into a feature that would benefit from low-level support, C# is a better fit than VB.NET. It's not that you can't manipulate an array in VB.NET, for example. It's that you can't do it as fast as in C# can in an unsafe block.
In general, option explicit off and option strict off will cripple performance. It's not that the process won't run, or won't compile. It's that every 2nd or 3rd line of code is boxing/unboxing. With implicit conversions, you have overhead at every assign, above and beyond box/unbox.
Generally speaking, my opinion is that Microsoft should have said "sorry, not supported anymore." Most apps require significant work to port anyway, so backwards compatibility didn't need to be a concern.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
It's all about options? This line of thinking seems to imply that a language should not "force" the developer to anything in particular, but only provide such things as type checking as an option. In my opinion, based on my experience, this is the best solution only in a completely academical and hopelessly unrealistic world. Can you give me a practical example of a situation in which weak typing is a real advantage?
I can see how *inferring* types can save some code with no loss of strictness, but I seriously do not understand how it can be disadvantegous to declare what type a variable is. It is true that we will sometimes get little benefit from strong typing, such as when we declare variables of type "object", but at the very least it forces the programmer to explicitly choose.
So, to me, the argument that "VB can do it" only scores half a point. Yes, it can do it, and that is a good thing, but it does not guarantee it, and that is a bad thing.
As for the volatile modifier, your response "what can I say" really does say it all and you'd have looked more honest if you had just plainly admitted there is no corresponding feature in VB.NET.
I'd agree that the VB.NET case statement is more powerful than C#'s, and I think it is weird that you haven't mentioned optional parameters. They can be of great benefit at times, particularly if you're coding against something like MS Office, where the APIs were designed for VBA and assume the caller can provide just the arguments he is interested in. Methods have up to 30 arguments, and it does little for the readability in C# to pass 29 default values and somewhere in there the one you're actually interested in using.
That said, I don't do much office interop and for me the choice is easy. With C# I only have to write half as much code as in VB, and this without the slighest drop in information. For the same reason I find it much easier to read. Finally, I must admit that I just cannot help myself for hating how VB tries to "improve" on long-established oop terminology with its "MustInherit Friend" classes and the like. For me, even though I understand intellectually that it is a perfectly usable language, it still feels like a baby's toy.
Lastly, you claim that VB is clearly superior to C#, while somewhat contradictory providing evidence that simple functions may require a 100% increase in memory consumption for a simple non-void method returning a value, and a 50% increase in stack size and a reduction in performance when doing string comparison (not exactly exotic, I might add). Yet you do not provide any clues as to what exactly it is that makes VB superior in your opinion.
Unless working with office interop, I see no compelling reason to choose VB, and if named parameters are added to C# as well I'm unaware of any area in which VB might be considered superior.
And nobody's even mentioned anything about the C#2.0 and 3.0 features. I haven't paid enough attention to know if VB has added anything similar... please enlighten me (us?)
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
By looking at all the comments about Vb vs C#, I can see lots of the fellwos are talking about OO.
But I have a question, do you really utilize the OO models? In this world, we are still using RDBM like SQL Server as the backend, and still manipulating recordset in mid-tier, and still using table styled data grid or data grid like front end tabular stuff. And all the reports are still tabular based (most of them). XML is not a solution for OO, it's just a serializable class formatter.
But here lots of folks are talking about OO design and implementation. I have seen really good OO design (costs the company tons of money to set the architecture). And see 99% of the company I have worked with are all OO claimed and has nothing to do with OO at all. All them implements are just inheretence and some interface design. They still use a controller based code to do real transaction or enquiry. That's not OO at all.
So please don't put OO as a word in your mouse all the time. Until a real OO database is matured in the market place, then lets talk about real OO.
Your comments,
Ian
|
| Sign In·View Thread·PermaLink | |
| | | | |