Delegate Covariance
Once again I slam into a VB.NET2005 limitation I’m told is fixed in 2008. 2008 sounds pretty hot.
Again, this post derives from adventures in Newsgroupland!
Here is what I was trying to do:
Public Class Part
End Class
Public Class SpecialPart
Inherits Part
End Class
Public Class FormManagerTest
Public Delegate Function PartGetter(ByVal id As Integer) As Part
Public Function GetPart(ByVal id As Integer) As Part
Return New Part
End Function
Public Function GetSpecialPart(ByVal id As Integer) As SpecialPart
Return New SpecialPart
End Function
End Class
Public Class Test
Sub Main()
Dim fm As New FormManagerTest
Dim getter1 As FormManagerTest.PartGetter
Dim getter2 As FormManagerTest.PartGetter
getter1 = AddressOf fm.GetPart
getter2 = AddressOf fm.GetSpecialPart
getter1.Invoke(1)
getter2.Invoke(1)
End Sub
End Class
This doesn’t work in vb.net 2005. The assignment to getter2 throws an error that the delegate does not match the specified type. The function returns a derived type of the delegate’s return type, but 2005 doesn’t give a damn about that.
Herfried K. Wagner gives me the most definitive answer (mostly because he told me the name of what I was trying to do). He basically said it’s not available in 2005 and that it’s available in 2008 and that that feature is named “Delegate Covariance”.
In software engineering, names are powerful beasts. It’s almost like some wacky D&D magic, you gain a lot of power by knowing someone’s name. A lot of people have coded various design patterns without knowing it, but until you know their names you can’t really discuss them with other people in any sort of concise fashion. Compare:
Dev1: “I coded this class for our application configuration object that is incapable of being directly instantiated and instead has a static member which ensures at runtime that a single instance exists at any given time across any number of threads.”
Dev2: “Our application configuration object is a Singleton.”
If i knew what Delegate Covariance was, I could have googled that, instead I was trying to google “delegate return type derived base” which is a far less specific query and yielded zero helpful results.
In fact one of the first results for Delegate Covariance is a blog entry by Francesco Balena from 2005(I’m so behind the times!). He even gives a psychotic workaround wherein he builds delegates via reflection at runtime. I plan on implementing this at my first convenience. :)
It ended up looking like this:Dim stockInfoFormGetterMethod As MethodInfo = formManager.GetType().GetMethod("GetStockInfoForm")
Dim stockInfoFormGetter As FormManager.FormGetter = DirectCast([Delegate].CreateDelegate(GetType(FormManager.FormGetter), formManager, stockInfoFormGetterMethod), FormManager.FormGetter)
formGetters = stockInfoFormGetter
Please note my example code and this production code have little to do with each other.
I would like to mention also that this code is insanely dense. I cannot recommend this as a technique to use commonly, simply because it’s so very gross. It’s brittle as well, since the getter is pulled by Name as a String. I use it once in my code, and once in a unit test. If it starts proliferating beyond those two instances I will reconsider my design post-haste.