Previous | Index | Next 

[HOWTO] Generate auto-implemented properties for Visual Basic 2010

Most VB6 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 this pragma tranforms 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 previous pragma, 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 This pragma deletes 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|City|ZipCode|Country)
           (?<type>\s+As\s+.+\r\n)", "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+
           \s*End Property\r\n", "" 

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", 

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

NOTE: even if generating auto-implemented properties is very simple, we recommend that you adopt this technique only during the optimization phase, at the very end of your migration project. A standard (non auto-implemented) property gives you more flexibility, allow you to trace assignments, allow you to set breakpoints, to validate incoming values, and so forth.


Previous | Index | Next