Welcome Guest!
Create Account | Login
Locator+ Code:

Search:
FTPOnline Channels Conferences Resources Hot Topics Partner Sites Magazines About FTP RSS 2.0 Feed

Click here to receive your FREE subscription to Visual Studio Magazine

email article
printer friendly
get the code

Reflecting on Generics
Determine whether an existing variable is a generic type and whether you have to use reflection in particular cases; create irregularly shaped forms; and enable remoting with single-instance applications.
by by Bill McCarthy

June 13, 2007

Technology Toolbox: VB .NET

Generics in .NET provide strong typing, high performance, and code reuse. In applications designed with generics in mind, generic parameters are passed throughout, enforcing constraints and providing the strong typing benefits. However, not all applications have the luxury of having been designed from the outset with generics in mind. Applications and frameworks written in .NET 1.0, 1.1, COM Interop, and even event-driven design still suffer from not having generic parameters available. The result is often an impedance mismatch, and gives rise to the one of the most frequent questions I get asked about generics: "How do I tell if this variable is a generic type?"

My first response to this is to question the question. Look at your code, look at your design, and see if you can factor it to either include generic parameters or to code completely without them. In the few cases where you do need to work with generic code from non-generic code, reflection allows you to build a bridge between the two.

One of the most common scenarios is trying to determine whether list items are of a particular type. For example, assume you have this class hierarchy:

Class Person
	...
Class Customer : Inherits Person
	...
Class Employee : Inherits Person

Now assume you have a routine that is meant to process Person objects from a List, and you are passed a List(Of Customer) as an Object:

Public Sub CallingCode
	Dim items as New List(Of Customer)
	ProcessPeople(items)
End Sub
....
Public Sub ProcessPeople(ByVal items _
	As Object)
	'work with items here
	'...
End Sub

Inside the ProcessPeople method, items is As Object. Now test to see whether items is a List(Of Person):

If TypeOf items Is GetType(List(Of _
	Person)) Then
ADVERTISEMENT

This test fails. The reason for the failure is that there is no generic variance: A List(Of Person) is not interchangeable with a List(Of Customer), even though Customer derives from Person. This is an important concept to understand when dealing with generics.

Variance would make it an easier task to test whether a List(Of Customer) is a list containing items that derive from Person, but it would also impede type safety. If the list's Item property were As Person, you could add any type to the list, as long as the type derives from Person. You would lose the type safety of ensuring that only Customers are in the list. In the future, VB and C# might get some kind of limited variance with generics, but a solution that makes it intuitive, yet preserves type safety, is some time away.

Today, the best solution for dealing with the items variable in this particular case is to refactor the method and provide a generic overload:

Public Sub ProcessPeople(Of T As Person) _
	(ByVal items As List(Of T))



Back to top













Java Pro | Visual Studio Magazine | Windows Server System Magazine
.NET Magazine | Enterprise Architect | XML & Web Services Magazine
VSLive! | Thunder Lizard Events | Discussions | Newsletters | FTPOnline Home