I write both VB and C#. Anyone who’s read this blog knows that I prefer C#, but VB is my company’s standard, so anything I write that will be deployed is written in VB. To keep my skills from decaying and in something of a silent protest, I do all of my prototyping and test code in C#. I have ReSharper 4.5 Full Edition installed, and although JetBrains states that 4.5 has enhanced VB9 support, I’m still amazed at how much more it does for me when I switch over to a C# project. It’s possible I don’t have it configured correctly, and I haven’t customized it at all yet (too busy coding, I guess). Either way, here’s an example of what ReSharper does with the exact same method, first in C#, then in VB.
The method is a simple string parsing method. I have a DB2 table full of strings. Somewhere in each string is an eight digit number that I need. However, this data was populated using a regular expression (^\D?\d{8}\D?$) that searched for all strings that have one non-digit wildcard before or after an eight digit string, which made room for situations where an octathorpe (#), parenthesis, colon, or anything else may have been directly in front of or following the desired string. Since the eight-digit string is all I really care about, here’s what might be a typical (albeit poorly written to accentuate ReSharper’s capabilities) little method to chop off the leading and/or trailing wildcard, if it exists, and return the meaningful eight digit string:
1: private String GetRealFieldData(string regexMatchData)
2: {
3: if (regexMatchData.Length == 10)
4: return regexMatchData.Substring(1, 8);
5: else if (regexMatchData.Length == 9)
6: {
7: if (System.Text.RegularExpressions.Regex.IsMatch(regexMatchData, @"^\D"))
8: return regexMatchData.Substring(1);
9: else
10: return regexMatchData.Substring(0, 8);
11: }
12: else
13: {
14: return regexMatchData;
15: }
16: }
Ugly, ain’t it? ReSharper thought so, too. Here’s what the snippet looks like in my IDE with ReSharper’s default options enabled:
Look at all of the possibilities that ReSharper found!
First is the method signature, which (since for this blog I put this code in a console application) can be made static. That’s pretty boring by ReSharper standards, but I went ahead and let it do it anyway, since it doesn’t really hurt anything and I am generally of the mind that members should have explicit and accurate modifiers.
Let’s get to the meat, which surrounds all of the if-else conditions. Notice that they are all grayed out, and that ReSharper put a green underline under the if’s. Anything that gets grayed out is unnecessary code, and I love brevity, so I told ReSharper (by hitting the default ALT+Enter keyboard combination to expand the little light bulb) to go ahead and fix the bad else’s, which resulted in this snippet:
1: private static String GetRealFieldData(string regexMatchData)
2: {
3: if (regexMatchData.Length == 10)
4: return regexMatchData.Substring(1, 8);
5: if (regexMatchData.Length == 9)
6: {
7: if (System.Text.RegularExpressions.Regex.IsMatch(regexMatchData, @"^\D"))
8: return regexMatchData.Substring(1);
9: return regexMatchData.Substring(0, 8);
10: }
11: return regexMatchData;
12: }
OK, that’s a little better.
But the real fun lies in the green underline under the embedded if statement, where Regex.IsMatch() is called. I was curious to see what the light bulb said, and even more curious after the light bulb offered a “Replace with ‘return’” option. So I let it rip, and was delighted to see the results, which will ultimately make me a better C# programmer since I learned a little more C# syntax.
1: private static String GetRealFieldData(string regexMatchData)
2: {
3: if (regexMatchData.Length == 10)
4: return regexMatchData.Substring(1, 8);
5: if (regexMatchData.Length == 9)
6: {
7: return System.Text.RegularExpressions.Regex.IsMatch(regexMatchData, @"^\D")
8: ? regexMatchData.Substring(1)
9: : regexMatchData.Substring(0, 8);
10: }
11: return regexMatchData;
12: }
Then, I took the same method in its original (crappy) form, and translated it to VB to see what ReSharper would do. Here’s the method again, VB this time:
1: Private Function GetRealFieldData(ByVal regexMatchData As String) As String
2: If regexMatchData.Length = 10 Then
3: Return regexMatchData.Substring(1, 8)
4: ElseIf regexMatchData.Length = 9 Then
5: If System.Text.RegularExpressions.Regex.IsMatch(regexMatchData, "^\D") Then
6: Return regexMatchData.Substring(1)
7: Else
8: Return regexMatchData.Substring(0, 8)
9: End If
10: Else
11: Return regexMatchData
12: End If
13: End Function
Even uglier than it was in C#, but I guess that depends on who’s looking. Here’s the view in my IDE:
Wow, that’s quite a difference! Aside from the method signature (VB console apps default you to Module1.vb rather than program.cs, so static/shared isn’t an issue here), none of the stuff that was marked by ReSharper in the C# version of this method is marked in the IDE for a VB application. However, the light bulbs still do show up, I just had to move through line by line to see them.
Going to the ElseIf statement brings up a bulb offering to change the if statement to a select case statement, but nothing is said about converting unnecessary else’s to returns. Also missing is the option to convert the Regex.IsMatch() condition to an If/Iif statement, my favorite part of the C# example.
So I guess the added support for VB in ReSharper 4.5 still lags well behind the power this plug-in provides for C# programmers. And you know what? I don’t blame JetBrains at all. I believe that ReSharper is as much a best practices tool as it is a productivity tool. When it comes to .Net best practices in books and online, a huge percentage of the examples you see are in C# rather than VB. I applaud Microsoft for supporting both languages as .Net moves forward, even though VB has been behind in several language features, but why would JetBrains spend a great deal of time and money integrating VB support into ReSharper when the majority of the developers that use their product are coding in C#? I have many more theories on this, which I’m sure I will expand on in days to come, and I’m hoping that I find ways to make ReSharper a better tool for VB coding. But for elegance, productivity, and best practices, the true value of this tool is still found in C#.