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