At first I was a bit sceptical, but after reading about it in so many blogs I just had to try ReSharper myself. So I did, and it is brilliant.
When I first went to their web site and read the writeup I thought it was just another VS.Net IDE enhancer, but boy was I wrong. (BTW. I think they should get someone else to do a writeup for resharper because theirs doesn't do it justice). I'm not going to list all the features or how it helps because I wont' be able to do it justice either. Just go to their site and download/install the trial. It will be worth it.
#include <stddisclaimer.h>
No I do not work for them or have any affiliation with them but if I did work for them I would definitely not be ashamed of it.
I was giving a course on .net (in particular VB.Net) and one of the attendees had the following code to check whether a radio button was checked
Select Case True
Case m_chkRadio1.Checked
MessageBox.Show("Radio1")
Case m_chkRadio2.Checked
MessageBox.Show("Radio2")
End Select
Coming from a C++ background, the above solution has never occurred to me, since in C++ (and Java and C#) the statement after "Case" must be constant. Never the less I thought it was interesting, and it started me off exploring the "select" and "switch" statements. What I found was surprising.
To start with, I wanted to do what VB.Net does with strings in the select statement. This is another thing you can't do in C#. I thus wanted to see what the following code would do
Select Case strVal
Case "MyString"
MessageBox.Show("MyString")
Case "MyInt"
MessageBox.Show("MyInt")
End Select
I suspected it would change this into a number of "If" statements, and when looking at the IL, I saw this assumption was correct.
Next I wanted to see what the following VB.Net select statement generates (This is also not doable from C#)
Select Case num
Case 1 To 3
MessageBox.Show("Was 1-3")
Case 4, 5
MessageBox.Show("Was 4,5")
Case 9 To 10
MessageBox.Show("Was 9-10")
End Select
I thought this would also create a number of if statements, but in this case my assumption was wrong. It generated the following IL.
IL_0005: switch (
IL_0034,
IL_0034,
IL_0034,
IL_0042,
IL_0042,
IL_005c,
IL_005c,
IL_005c,
IL_0050,
IL_0050)
IL_0032: br.s IL_005c
IL_0034: nop
IL_0035: ldstr "Was 1-3"
IL_003a: call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string)
IL_003f: pop
IL_0040: br.s IL_005c
IL_0042: nop
IL_0043: ldstr "Was 4,5"
IL_0048: call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string)
IL_004d: pop
The IL generated created a switch statement with a jump table for all the values, 1 through 10. The values that was not in the select statement (6,7,8) was just set to jump to some code that did a no-op. This was indeed very interesting. I obviously had to tempt fate and wanted to see what the following generates:
Select Case num
Case 1 To 3
MessageBox.Show("Was 1-3")
Case 4, 5
MessageBox.Show("Was 4,5")
Case 9 To 10
MessageBox.Show("Was 9-10")
Case 34423 To 34490
MessageBox.Show("Very Big")
End Select
As you can see, the last "case" has a very big number. It would thus not be feesable to generate a switch statement with all the values 1-34490. What it generated was disappointing, but understandable, It once again generated a number of "if" statements for all the values specified in the select statement.
Having learned a number of things, I thought I'd have a look at what C# generates. It's results was also interesting, but not as surprising since the VB.Net compiler already set the precedent.
Let's start with the simple case
switch (num)
{
case 1:
MessageBox.Show( "Was 1");
break;
case 2:
MessageBox.Show( "Was 2");
break;
}
This generates (as expected) IL code that makes use of the "switch" IL instruction.
If we now look at the following code, which as 2 consecutive number followed by a large number, the generated IL differs from the VB.Net generated IL. If we have
switch (num)
{
case 1:
MessageBox.Show( "Was 1");
break;
case 2:
MessageBox.Show( "Was 2");
break;
case 16123:
MessageBox.Show( "Was big");
break;
}
The IL generated is actually
IL_0005: switch (
IL_001c,
IL_0029)
IL_0012: ldloc.0
IL_0013: ldc.i4 0x3efb
IL_0018: beq.s IL_0036
IL_001a: br.s IL_0043
IL_001c: ldstr "Was 1"
IL_0021: call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string)
IL_0026: pop
IL_0027: br.s IL_0043
In other words, it starts off with a switch statement for the consecutive numbers, and after that changes to an "if" statement. This differs from the VB.Net compiler which doesn't try any intelligence like this, but directly switches (pardon the pun) into "if statement" mode. I naturally had to try the following:
switch (num)
{
case 1:
MessageBox.Show( "Was 1");
break;
case 2:
MessageBox.Show( "Was 2");
break;
case 16123:
MessageBox.Show( "Was big");
break;
case 16124:
MessageBox.Show( "Was big");
break;
case 16125:
MessageBox.Show( "Was big");
break;
}
This generated 2 sets of "switch" il statements. One switch statement for each set of consecutive numbers. Now that was really impressive. I gave the above switch statement a go in VB.Net as well but suspected that it would still only generate a number of "if" statements. This suspicion proved to be correct.
This was interesting not only because it showed better generated IL in C# than for VB.Net, but also because it showed that the code generated in C# is making an attempt to be optimal. So far I was very impressed with the IL generated from C#, and just to play devil's advocate, I had to try the following
switch (num)
{
case 1:
MessageBox.Show( "Was 1");
break;
case 16123:
MessageBox.Show( "Was big");
break;
case 16124:
MessageBox.Show( "Was big");
break;
case 2:
MessageBox.Show( "Was 2");
break;
case 16125:
MessageBox.Show( "Was big");
break;
}
And yes, it does what one hopes it does. It generates 2 IL switch statements with the consecutive numbers grouped together.
All I can say is "Impressive"