2D Head with a clock as an eyeball.
 Wednesday, June 11, 2008

Today Resharper 4.0 goes RTM, if you haven't been following the EAP, you might be interested to know that we now have full C# 3.0 language and LINQ support.

That's not all we get, there are a swag of cool new refactorings, solution wide code analysis, extra framework annotations, camel humps in code completion....the list just goes on.

There are some improvements to the VB experience like new refactorings only previously supported in C# 2.0:

  • Convert Method to Property
  • Convert Property to Method
  • Pull Members Up
  • Push Members Down
  • Extract Interface
  • Extract Superclass
  • Convert Interface to Abstract Class
  • Convert Abstract Class to Interface
  • Extract Class from Parameters
  • Use Base Type Where Possible
  • Replace Constructor with Factory Method
  • The ASP.NET guys don't miss out either, amongst other things - a performance increase to page analysis, which has been a real problem for large ASP.NET pages in the past.

    Personally, I find Resharper to be the best C# productivity tool out there for the money, and they are paying more and more attention to VB.NET. Combined with Viemu its my productivity suite of choice and I encourage you to give them both a try.


    Filed under:  |  |  | 
     Friday, March 14, 2008

    Hey y'all, long time no see. Life has thrown me a few curve balls which impeded my blogability, but rather than boring you with details lets just get into straight into it.

    Recently I've had a few queries regarding a check in policy I eluded to in this post. Today I hope to clarify how one might go about implementing a check in policy which ensures that Option Strict is turned on for VB projects.

    Rather than rehashing a perfectly good walk through, I suggest you read this article from MSDN to get the basics of Check In Policy creation.

    Once we have our check in policy project and have derived a class from Microsoft.TeamFoundation.VersionControl.Client.PolicyBase it is time to start overriding the behaviour of the base rule.

    Imports Microsoft.TeamFoundation.VersionControl.Client
    
    <Serializable()> _
    Public Class OptionStrictPolicy
        Inherits PolicyBase

    Once we are over that little hurdle we want to:

    * Get the set of pending changes that have been selected by the user to check in

    * For each pending change determine the project file that the change belongs to

    * For each VB project determine if Option Strict has been turned on

    * For each project that hasn't got option strict turned on, create a policy warning.

    For extra fun I'll do this all with VS2008 & VB9. I love my C# but to be honest VB9 kicks its ass when dealing with XML.

    1: Get the set of pending changes that have been selected by the user to check in

    Everything from here on out extends the Evaluate method of PolicyBase. Getting the set pending changes selected by the user is a cinch. I've filtered by vb code files, but you could just as easily go for more file types.

    Public Overrides Function Evaluate() As PolicyFailure()
    
      Dim pendingChanges = PendingCheckin.PendingChanges.CheckedPendingChanges
      Dim vbCodeFiles = _
        From c In pendingChanges _
        Let extension = Path.GetExtension(c.FileName) _
        Where extension = _VBFileExtension OrElse extension = _VBProjectFileExtension _
        Select c.LocalOrServerFolder, c.FileName

    2: For each pending change determine the project file that the change belongs to

    This step is a little trickier and basically involves drilling up the folder structure until we find a project file, and then checking the project file for a compilation reference to the pending change. This seems like a good place to refactor into a recursive function...

    *SIDE NOTE* Am thinking of starting a petition to all relevant Dictionary makers to make the word "Refactor" a real word. Whose with me?

    I'm sure we are all capable of looking for .vbproj files recursively up the folder chain. However we do need to allow for the possibility that there may be two vbproj files in a folder and if so, is our pending change referenced by either of them? To do this I need to go through the project file looking for <Compile> tags that include my pending change. For example in C# we might do it like this

    var doc = XDocument.Load(XmlReader.Create(projectFilename));
    var compileItems = from e in doc.Descendants()
        where e.Name.LocalName == "Compile"
        select e;
        
        return (from c in compileItems
          where c.Attribute("Include") != null && c.Attribute("Include").Value.Contains(filename)
          select c).Any();

    But since Im using VB today I can do it like this...

    Dim doc = XDocument.Load(XmlReader.Create(projectFilename))
    Return doc...<Compile>.@Include.Contains(filename)

    Not bad...but for this to work I do need to import the namespace of the project file schema, since the syntax that allows for <Compile> is checking qualified names, not local names.

    Imports <xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    3: For each VB project determine if Option Strict has been turned on

    Once I have a list of projects that are loosely associated with a check in, I can easily check for the existence of OptionStrict tags in the vbproj file. OptionStrict still defaults to off, so a lack of OptionStrict tags implies the setting is OFF. However it is perfectly valid to have an OptionStrict tag that is set to OFF so I need to account for those.

    Private Shared Function IsOptionStrictOn(ByVal project As XDocument) As Boolean
        Return project...<OptionStrict>.Value = "On"
    End Function

     

    4. For each project that hasn't got option strict turned on, create a policy warning.

    Creating policy warnings is a breeze and you can return as many as you want, in this scenario I want to ensure that one is created for each project that is in violation of my rule. The final Evaluate function looks like this...

    Public Overrides Function Evaluate() As Microsoft.TeamFoundation.VersionControl.Client.PolicyFailure()
      Dim pendingChanges = PendingCheckin.PendingChanges.CheckedPendingChanges
    
      Dim vbCodeFiles = From c In pendingChanges _
        Let extension = Path.GetExtension(c.FileName) _
        Where extension = _VBFileExtension OrElse extension = _VBProjectFileExtension _
        Select c.LocalOrServerFolder, c.FileName
    
      Dim vbProjects = From c In vbCodeFiles _
        Select GetProjectFile(c.LocalOrServerFolder, c.FileName)
    
      Dim strictOffprojects = From p In vbProjects _
        Where Not IsOptionStrictOn(p)
    
      Dim policyFailures = New List(Of PolicyFailure)
      Dim messageFormat = "Please turn option strict on in the project file: {0}"
    
      For Each s In strictOffprojects.Distinct
        policyFailures.Add(New PolicyFailure(String.Format(CultureInfo.InvariantCulture, messageFormat, s), Me))
      Next
    
      Return policyFailures.ToArray()
    End Function

     

    So there you have it, VB9 to make coding an Option Strict ON policy nice and easy. Seems appropriate doesn't it?


    Filed under:  |  |  |  | 
     Wednesday, July 18, 2007

    9421665_f055539a8c_mFound this gem today, and yes - I wrote it.

    Its a very simple class, I use it to tell NCover to ignore certain sections of code - fair enough right? Well... here it is.

    <CoverageExclude()> _
    Friend NotInheritable Class CoverageExcludeAttribute
        Inherits System.Attribute
    End Class

    Embarrassing. You can see another example of this kind of logic here.

    So hands up people - give us your most recent stupid coding moment and make me feel better about myself.


    Filed under:  |  |  | 
     Thursday, June 21, 2007

    This may not be news to some of you, and for you I apologize. For the rest, please avoid using MsgBox in VB .NET projects, and use MessageBox.Show instead.

    MsgBox is a wrapper around the MessageBox.Show method and is meant for backwards compatibility with older VB projects. It should be left for those who really can't do without it.

    A common misuse for message boxes is debugging code, and most people have invariably found the following code snippet lazing about in production code from time to time:

       Try
          'Some error prone code
       Catch ex as SomeException
          MsgBox(ex)
       End Try

    The problem with this 'debugging' code is that in certain circumstances it will cause bugs of its own. Beware of MsgBox throwing exceptions. I'm not referring to just the documented InvalidOperationExceptions either. If the exception does something interesting in its overload of ToString, or if the MsgBox function fails when determining the title of the message box then anything from StackOverFlowExceptions to OutOfMemoryExceptions can occur.

    But wait…..there's more, another issue is localisation. If you are using FxCop and have turned on System.Globalization, any call to MessageBox.Show must specify the RTL nature of the box to be shown. The problem with MsgBox is that while it does some fancy work to determine the title, it doesn't bother determining the RTL nature of the parent window. The CA rule doesn't appear to have been written to take calls to MsgBox into consideration. In short, calls to MsgBox break the Globalisation rule CA1300.


    Filed under:  |  |  | 
    © Copyright 2008 Jim Burger