Philip,
I'm sure you could kludge together something with Reflection. However I have
to ask why?
Using Reflection I'm certain would be more fragile, and perform
significantly worse (as late binding or Reflection pretty much always
perform worse), and possibly be harder to follow. Granted double dispatch is
a little more advance then normal overridable functions, however not that
much more as you are simply having an overridable function call an
overridable function.
Also I don't think Reflection you are really going to save on the number of
functions you need (see below).
Try single stepping the following version to see how the double dispatch
works.
---x--- cut here ---x---
Public MustInherit Class C
Public Sub F(ByVal aC As C)
aC.Fc(Me)
End Sub
Public MustOverride Sub Fc(ByVal aC As C)
' NOTE we use qualified names rather then overloading here
' we could have just as easily call these all Fc...
Public MustOverride Sub Fc1(ByVal aC1 As C1)
Public MustOverride Sub Fc2(ByVal aC2 As C2)
Public MustOverride Sub Fc3(ByVal aC3 As C3)
Public MustOverride Sub Fc4(ByVal aC4 As C4)
End Class
Public Class C1
Inherits C
Public Overrides Sub Fc(ByVal aC As C)
aC.Fc1(Me)
End Sub
Public Overrides Sub Fc1(ByVal aC1 As C1)
Debug.WriteLine("Fc1(c1)", "c1")
End Sub
Public Overrides Sub Fc2(ByVal aC2 As C2)
Debug.WriteLine("Fc2(c2)", "c1")
End Sub
Public Overrides Sub Fc3(ByVal aC3 As C3)
Debug.WriteLine("Fc3(c3)", "c1")
End Sub
Public Overrides Sub Fc4(ByVal aC4 As C4)
Debug.WriteLine("Fc4(c4)", "c1")
End Sub
End Class
Public Class C2
Inherits C
Public Overrides Sub Fc(ByVal aC As C)
aC.Fc2(Me)
End Sub
Public Overrides Sub Fc1(ByVal aC1 As C1)
Debug.WriteLine("Fc1(c1)", "c2")
End Sub
Public Overrides Sub Fc2(ByVal aC2 As C2)
Debug.WriteLine("Fc2(c2)", "c2")
End Sub
Public Overrides Sub Fc3(ByVal aC3 As C3)
Debug.WriteLine("Fc3(c3)", "c2")
End Sub
Public Overrides Sub Fc4(ByVal aC4 As C4)
Debug.WriteLine("Fc4(c4)", "c2")
End Sub
End Class
Public Class C3
Inherits C
Public Overrides Sub Fc(ByVal aC As C)
aC.Fc3(Me)
End Sub
Public Overrides Sub Fc1(ByVal aC1 As C1)
Debug.WriteLine("Fc1(c1)", "c3")
End Sub
Public Overrides Sub Fc2(ByVal aC2 As C2)
Debug.WriteLine("Fc2(c2)", "c3")
End Sub
Public Overrides Sub Fc3(ByVal aC3 As C3)
Debug.WriteLine("Fc3(c3)", "c3")
End Sub
Public Overrides Sub Fc4(ByVal aC4 As C4)
Debug.WriteLine("Fc4(c4)", "c3")
End Sub
End Class
Public Class C4
Inherits C
Public Overrides Sub Fc(ByVal aC As C)
aC.Fc4(Me)
End Sub
Public Overrides Sub Fc1(ByVal aC1 As C1)
Debug.WriteLine("Fc1(c1)", "c4")
End Sub
Public Overrides Sub Fc2(ByVal aC2 As C2)
Debug.WriteLine("Fc2(c2)", "c4")
End Sub
Public Overrides Sub Fc3(ByVal aC3 As C3)
Debug.WriteLine("Fc3(c3)", "c4")
End Sub
Public Overrides Sub Fc4(ByVal aC4 As C4)
Debug.WriteLine("Fc4(c4)", "c4")
End Sub
End Class
Public Class Test
Public Shared Sub Main()
Dim xlist() As C = {New C1, New C2, New C3, New C4}
Dim ylist() As C = {New C1, New C2, New C3, New C4}
For Each x As C In xlist
For Each y As C In ylist
Debug.WriteLine(x, "x")
Debug.WriteLine(y, "y")
x.F(y)
Debug.WriteLine(Nothing)
Next
Next
End Sub
End Class
---x--- cut here ---x---
If you are really not following the double dispatch I would recommend you
use a select case as you originally suggested and avoid reflection. As the
select case will be easier to understand and perform better then using
Reflection.
However! I recommend Double Dispatch as it is a rather common OO method to
solve the problem you seem to be stating. For example: The Visitor Pattern
is commonly implemented as Double Dispatch in single inheritance languages
such as VB.NET & C#.
I don't suppose you know of any way I can do it using Reflection and the
Type object etc? It would be nice to avoid writing two functions for every
one I need.
Why do you think there are twice as many as you need?
You need (N+1)^2 functions, you write (N+1)^2 functions. Your original post
suggested class C1 to CN need functions F(C1) to F(CN), the double dispatch
code has F(C1) to F(CN) + F(C) in each class, which for an number of N > 1
does not add up to "twice as many"...
In other words with Double Dispatch, if you have N classes you need N
functions per class, plus you need 1 extra function per class that actually
does the double dispatch.
Your original post suggested if you have N classes you would have N
functions per class (as all the functions were MustOverride). Double
dispatch is simply adding +1 to each class.
In both cases you have an abstact base class, simply to define what the
above classes need to look like. Of course if some combinations of F(C1) to
F(CN) are not logical you could always leave them in the base class as
simply Overridable & provide "default" implementation for all the derived
classes...
Unfortunately I am not seeing any really good links on double dispatch.
Hope this helps
Jay
"Philip Warner" <Ph**********@discussions.microsoft.com> wrote in message
news:5F**********************************@microsof t.com...
It sounds like you want a double dispatch.
Thanks for this; it's very long-winded but it will achieve the result.
I don't suppose you know of any way I can do it using Reflection and the
Type object etc? It would be nice to avoid writing two functions for every
one I need.