Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB

An Almost Extension Property

5.00/5 (3 votes)
27 Mar 2016CPOL2 min read 16.2K   39  
How to fake an Extension Property...

Introduction

Extension methods (Function or Sub) are a powerful tool to extend an otherwise sealed object. It's easier than creating a Class extension because you do not need to update your (maybe already deployed) code, e.g. change Dim nice As SomeClass to Dim nice As SomeClassExtendedAndNicer. Obviously, different situations call for different solutions and you need an extended Class, but I prefer extension methods if I can solve the situation with those. One big huge drawback with extension methods is that you cannot write extension properties! See on MSDN here.

In this tip, I show how to (ab)use the Tag property for a proxy of an extension property or AlmostExtensionProperty. This tip was inspired by a Q&A on StackOverflow: VB extension property instead of extension method.

Code Example

First, we need a Class to function as container for some extra extension properties. This Class you would write for an ExtendedClass or an AlmostExtensionProperty alike:

VB.NET
Public Class ExtendedProps
    Public StrA As String = "A"
    Public DblB As Double = 2
    Public BoolC As Boolean = True
    
    'etc...
    
End Class

I will use a Forms Label control as an example and with an ExtendedClass you would or could code something like this:

VB.NET
Public Class ExtendedLabel
    Inherits Label
    
    Public Sub New()
        MyBase.New
        _extProps = New ExtendedProps
    End Sub
    
    Private _extProps As ExtendedProps = Nothing
    
    Public Property ExtraProperties() As ExtendedProps
        Get
            Return _extProps
        End Get
        Set
            _extProps = value
        End Set
    End Property
End Class

Nothing new so far. Now creating an AlmostExtensionProperty would call for an Extension Module and (mis)use the Tag object of the Label control like this:

VB.NET
Imports System.Runtime.CompilerServices
Public Module Extensions
    <Extension()>
    Public Function GetMoreProps(ByVal thisLabel As Label) As ExtendedProps
        Try
            Return CType(thisLabel.Tag,ExtendedProps)
        Catch
            Return Nothing
        End Try
    End Function
    
    <Extension()>
    Public Function SetMoreProps(ByVal thisLabel As Label, extraProps As ExtendedProps) As Boolean
        Try
            thisLabel.Tag = extraProps
            Return True
        Catch
            Return False
        End Try
    End Function
End Module

Two Extension methods which expose the ExtendedProps class through the label's Tag object is all you need. Now if you create a form with two labels on it (one regular System.Windows.Forms.Label and another special ExtendedLabel), you can test the ExtendedProps:

VB.NET
Public Class Main 'form
    Public Sub New()
        'Just a form with two Label controls:
        'Dim labExtendedLabelClass As New ExtendedLabel()
        'Dim labAlmostPropExt As New Label()
        'Me.InitializeComponent()
        
        labAlmostPropExt.SetMoreProps(New ExtendedProps)
        Debug.Print("Property StrA from a Label with an AlmostPropertyExtension = " & _
                     labAlmostPropExt.GetMoreProps.StrA)
        
        Debug.Print("Property StrA from a Label extended class = " & _
                     labExtendedLabelClass.ExtraProperties.StrA)
        
    End Sub
End Class

Running this form will give you the following output:

VB.NET
Property StrA from a Label with an AlmostPropertyExtension = A
Property StrA from a Label extended class = A

Different method, similar result.

Points of Interest

Indeed, a probably less common use of the Tag property. However, to all accusations of improper coding, I shall answer: "Who told you the coding world is proper...?"

History

  • March 25th, 2016: First published

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)