Generic Variance Part1 : Do you really need it ?
Posted
Mon, Aug 11 2008 14:21
by
bill
Lucian has kicked off the conversation on generic variance in VB , so I thought I’d write a few posts outlining my perspectives on the subject… the first of which is this one, and what better place to start than to question whether or not it is really needed……
Generics came to .NET after the base framework and languages were implemented. It was very much a bolt-on approach. As such there was and still is an impedance mismatch between conventional concepts of polymorphism and generics. As I posted previously, I had raised this is issue with Anders and other language experts back at the 2003 PDC (at which time Anders suggested using a language other than VB or C# <g>). Fast forward to today, and this issue is now being looked at, but now I find myself questioning if it is really needed, or is the fault the mismatch of the original framework.
Let’s take Lucian’s example :
Dim args As New List(Of ConstantExpression)
args.Add(Expression.Constant(2))
args.Add(Expression.Constant(3))
Dim y = Expression.Call(instance, method, args)
This code fails because the Call method is defined as :
Public Shared Function [Call](ByVal instance As Expression, _
ByVal method As MethodInfo, _
ByVal arguments As IEnumerable(Of Expression)) _
As MethodCallExpression
But if it was defined as follows then the code would work:
Public Shared Function [Call](Of T As Expression) _
(ByVal instance As Expression, _
ByVal method As MethodInfo, _
ByVal arguments As IEnumerable(Of T)) _
As MethodCallExpression
So where exactly is the problem ? The simple rule is if you want polymorphism (read as “generic variance”) in your code, then you need to expose the types as generic parameters not as concrete types.
That is, the above is solved by better API design and some simple refactoring. This in fact solves 90% or more of all the cases I have seen. The one place where you can’t do this is when the type is late bound and defined only as Object (more on this in a future post no doubt ;))