dougherty distilled

Bryan Dougherty's thoughts on technology and software development.
in

Finding an Instance of a Custom Generic Type at Runtime

Sometimes we write .NET code that needs to behave differently based on the type of the instance it is working with.  In other words, branched logic based on type.  In a custom collection, for example, we may have logic that says "if the item added is of my custom item type then check one of its properties."  An example in the .NET Framework is the DataGridView.  It behaves differently based on the type of the data source that was set.  One set of behaviors for an ArrayList and additional logic for a DataSet.

Usually the following code would satisfy the need:

   If TypeOf _dataSource Is DataSet Then...

This type of detection gets a little tricky when your writing code to try to find a Generic class that you don't know the type parameter for.

Assume you defined the following classes:

Public Class SomeCollection

   Public Sub Add(anyItem as Object)

      ' If anyItem is SomeObject

      ' check the SomeInfo Property

   End Sub

End Class

Public Class SomeObject(Of TInnerObject)

   Public ReadOnly Property SomeInfo As String

      Get

         Return _info

      End Get

   End Property

End Class

The first class is a collection that allows any item to be added to it.  The second class is a Generic class that you will sometimes add to your custom collection.  If SomeCollection always wanted to check the property SomeInfo on a SomeObject if it were added, you couldn't easily write the code to do so because you don't know what the type parameter for the instance is.  In other words, you don't know to put in place of the question mark below:

   If TypeOf anyItem Is SomeObject(Of ?

There are two similar ways to go about solving this problem.  The first is to declare an Interface that SomeObject implements. 

Public Interface ISomeObject

   ReadOnly Property SomeInfo As String   

End Interface

Then you can write the code as

   If TypeOf anyItem Is ISomeObject Then...

What I prefer is to create a base class for your Generic object that has the same name but no type parameter and forces the implementation in the derived Generic class.  I think it is more readable and potentially easier to manage.

Public MustInherit Class SomeObject

   Public MustOverride ReadOnly Property SomeInfo As String

End Class

Public Class SomeObject(Of TInnerObject)

   Inherits SomeObject

   Public Overrides ReadOnly Property SomeInfo As String

      Get

         Return _info

      End Get

   End Property

End Class

This way you can add the following code in SomeCollection's Add method:

   If TypeOf anyItem Is SomeObject Then...

 

Comments

No Comments

Leave a Comment

(required) 

(required) 

(optional)

(required)