PITADEV
Curiosity killed the developer's project.

ReSharper C# FTW (again), VB not so much

Wednesday, 3 June 2009 13:24 by aj

resharper 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:

ResharperCs1

Look at all of the possibilities that ReSharper found!

ResharperCs2First 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.

ResharperCs3 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.

ResharperCs4   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:

ResharperVb1

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.  ResharperVb2 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#.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:  
Categories:   C# | Tools | VB | Visual Studio
Actions:   E-mail | del.icio.us | Permalink | Comments (4) | Comment RSSRSS comment feed

Comments