As our customers already knows, starting with version 1.30 VB Migration Partner can generate Visual Basic 2010 projects and solutions. In this short article I'll illustrate how you can generate code that leverages one of the coolest new features of VB2010: auto-implemented properties.

To see when and why auto-implemented properties can be useful, consider that most properties are just wrappers for a private variable, as in the following example:

Private m_ID As Long
Private m_Name As String

Public Property Get ID() As Long
    ID = m_ID
End Property

Public Property Get Name() As String
    Name = m_Name
End Property

Public Property Let Name(ByVal value As String)
    m_Name = value
End Property

When converted through VB Migration Partner, the above code generates these VB.NET statements:

Private m_ID As Integer
Private m_Name As String = ""

Public Readonly Property ID() As Integer
        Return m_ID
    End Get
End Property

Public Property Name() As String
        Return m_Name
    End Get
    Set(ByVal value As String)
        m_Name = value
    End Set
End Property

In cases like this – that is, when a property is merely a wrapper for a private variable and doesn’t perform any additional action – you can generate a new cool feature of Visual Basic 2010: auto-implemented properties. In fact, in VB2010 you can rewrite the above code block with just two lines:

Public ReadOnly Property ID As Integer
Public Property Name As String = ""

VB Migration Partner doesn’t include an explicit option to generate auto-implemented properties. However, you can easily tweak the converted VB2010 code to reach this goal. In fact, you just need three pragmas:

'## REM tranform the variable declaration into an implemented property
'## PostProcess "\b(Dim|Private)\s+m_(?<prop>Name)(?<type>\s+
        As\s+.+\r\n)", "Public Property ${prop}${type}"

'## REM same as above, but this is for readonly properties
'## PostProcess "\b(Dim|Private)\s+m_(?<prop>ID)(?<type>\s+
        As\s+.+\r\n)", "Public ReadOnly Property ${prop}${type}"

'## REM delete the Property procedures
'## PostProcess "[ \t]*(Public|Friend|Private)\s+(ReadOnly\s+)?Property
        \s+(ID|Name)\b.+\r\n(.+\r\n)+?\s*End Property\r\n", ""

The interesting point is that you need only three pragmas regardless of how many properties you want to process. For example, suppose that you have a class that contains 8 properties that can be transformed into auto-implemented properties:
    FirstName, LastName, Address, City, ZipCode, Country  (read-write)
    ID, Age (read-only)
These are the three pragmas that you need:

'## PostProcess "\b(Dim|Private)\s+m_(?<prop>FirstName|LastName|Address|
        "Public Property ${prop}${type}"

'## PostProcess "\b(Dim|Private)\s+m_(?<prop>ID|Age)(?<type>\s+As\s+
        .+\r\n)", "Public ReadOnly Property ${prop}${type}"

'## PostProcess "[ \t]*(Public|Friend|Private)\s+(ReadOnly\s+)?Property\s+
        (.+\r\n)+?\s*End Property\r\n", ""

Cool, uh?

NOTE: If the original VB6 code accesses the private variable outside the property procedure, you need one more pragma to ensure that all references to the variable are rendered as referenced to the property

'## PostProcess "\bm_(?<prop>FirstName|LastName|Address|City|ZipCode|
        Country|ID|Age)\b", "${prop}"

Also notice that if the property is marked as ReadOnly and you access the inner variable in places other than the Class_Initialize event handler, than you can't render the property as an auto-implemented property.