Principles of Software Design: DQK
Comments off
Comments off
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.
Comments off
Ok enough crazy posts about divine design beings shining down on me from up on high. That’s what too much caffeine on an empty stomach does to a person!
So I’m beginning to hate VB.NET. Yup. There, I said it.
I was trying to create a read only interface to a Part object.
Public Interface IReadOnlyPart
ReadOnly Property PartNumber() As String
End Interface
And Have a Part Class Implement that Interface like this:
Public Class Part
Implements IReadOnlyPart
Public Property PartNumber As String _
Implements IReadOnlyPart.PartNumber()
Etc.
That doesn’t work in VB. You can’t inherit a readonly property from an interface and then make it read/write. Grr! I’m told you can do this in C#, but I haven’t confirmed this. I posted an inquiry to microsoft.public.dotnet.languages.vb and got some great responses. This is the proposed solution by Steve Gerrard which, while perverse, works wonderfully.
Public Class Class1
Implements IReadOnlyPart
Private PartNum As String
Private ReadOnly Property Dummy() As String _
Implements IReadOnlyPart.PartNumber
Get
Dummy = PartNum
End Get
End Property
Public Property PartNumber() As String
Get
PartNumber = PartNum ' or Dummy
End Get
Set(ByVal Value As String)
PartNum = Value
End Set
End Property
End Class
Sample test code:
Dim o As Class1 = New Class1
Dim p As IReadOnlyPart = o
o.PartNumber = "test 001"
Debug.WriteLine("Class1: " + o.PartNumber)
Debug.WriteLine("IReadOnlyPart: " + p.PartNumber)
I never would have figured that out. Always ask for help when in over your head. I’ve got another post brewing on that same mailing list now about delegates.
Grr @ Delegates! So sexy, but so pointy.
Comments off
Things have changed considerably since last we really talked. Come on. Pull up a seat. Get cozy and let’s dish.
Firstly, I moved! I live in Ellensburg, Washington now. It’s amazingly beautiful here. I’m smitten.
Secondly, I have a new job. I work at JMT Systems Consulting. My title is “Systems Analyst”, but it turns out I’ll be wearing many hats. Good thing I have a big head (size 7-3/4 for those interested). It’s been a great experience. It’s a really great environment with really great people and I’m really happy to be here. Really.
I have some more posts coming up. So much new stuff! Document-Based Databases are poking my brain in all the right places. Map/Reduce is delicious. Oh and look at this Unit Testing Pattern which straight up wins the “Best Name for a Design Pattern Ever” award: ObjectMother.
Now that’s a mother of a pattern right there.
Comments off