473,386 Members | 1,753 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Best way to call inherited method with var of base class?


I have a set of classes:

C (base)
C1 (inherits C)
C2 (inherits C)
...
Cn (inherits C)

(the C1..Cn also have subclasses, but thats not really relevant to the
question)

C has the following functions:

F(C) (implemented in C)
F(C1) (mustoverride)
...
F(Cn) (mustoverride)

When I declare two variables (x, y) of type C, and call x.F(y), it calls the
base class implementation of F(C) which is quite understandable. However, I
would like to actually call the appropriate F(Cn) based on the actual classes
of x & y.

What is the best way of doing this?

Currently I have a case statement inside F(C), which is (a) bad for
maintenance and (b) a kludge.
Nov 21 '05 #1
6 2118
"Philip Warner" <Ph**********@discussions.microsoft.com> schrieb:
I have a set of classes:

C (base)
C1 (inherits C)
C2 (inherits C)
...
Cn (inherits C)

(the C1..Cn also have subclasses, but thats not really relevant to the
question)

C has the following functions:

F(C) (implemented in C)
F(C1) (mustoverride)
...
F(Cn) (mustoverride)

When I declare two variables (x, y) of type C, and call
x.F(y), it calls the base class implementation of F(C) which
is quite understandable. However, I would like to actually
call the appropriate F(Cn) based on the actual classes
of x & y.


http://groups.google.de/groups?selm=...TNGP11.phx.gbl

--
Herfried K. Wagner [MVP]
<URL:http://dotnet.mvps.org/>
Nov 21 '05 #2
"Herfried K. Wagner [MVP]" wrote:

http://groups.google.de/groups?selm=...TNGP11.phx.gbl


I think you *may* have missed the point; I am not trying to call the base
class methods directly, I asm trying to ensure that the narrowest possible
function signature is used.

I can understand why VB needs to obey the class of the variable
declarations, but the question is: if I *want* to call the narrower function
based on the class of the parameters, what is the best way to do it?

In my specific example, I only have one level of inheritance, and there is
no code in the base class.

Nov 21 '05 #3
Philip.
When I declare two variables (x, y) of type C, and call x.F(y), it calls
the
base class implementation of F(C) which is quite understandable. However,
I
would like to actually call the appropriate F(Cn) based on the actual
classes
of x & y. It sounds like you want a double dispatch. Try something like:

Public MustInherit Class C

Public MustOverride Sub F(ByVal aC As C)
Public MustOverride Sub F(ByVal aC1 As C1)
Public MustOverride Sub F(ByVal aC2 As C2)
Public MustOverride Sub F(ByVal aC3 As C3)

End Class

Public Class C1
Inherits C

Public Overloads Overrides Sub F(ByVal aC As C)
' Me is now C1, so C.F(C1) is called
aC.F(Me)
End Sub

Public Overloads Overrides Sub F(ByVal aC1 As C1)
Debug.WriteLine("F(c1)", "C1")
End Sub

Public Overloads Overrides Sub F(ByVal aC2 As C2)
Debug.WriteLine("F(c2)", "C1")
End Sub

Public Overloads Overrides Sub F(ByVal aC3 As C3)
Debug.WriteLine("F(c3)", "C1")
End Sub

End Class

Public Class C2
Inherits C

Public Overloads Overrides Sub F(ByVal aC As C)
' Me is now C2, so C.F(C2) is called
aC.F(Me)
End Sub

Public Overloads Overrides Sub F(ByVal aC1 As C1)
Debug.WriteLine("F(c1)", "C2")
End Sub

Public Overloads Overrides Sub F(ByVal aC2 As C2)
Debug.WriteLine("F(c2)", "C2")
End Sub

Public Overloads Overrides Sub F(ByVal aC3 As C3)
Debug.WriteLine("F(c3)", "C2")
End Sub

End Class

Public Class C3
Inherits C

Public Overloads Overrides Sub F(ByVal aC As C)
' Me is now C3, so C.F(C3) is called
aC.F(Me)
End Sub

Public Overloads Overrides Sub F(ByVal aC1 As C1)
Debug.WriteLine("F(c1)", "C3")
End Sub

Public Overloads Overrides Sub F(ByVal aC2 As C2)
Debug.WriteLine("F(c2)", "C3")
End Sub

Public Overloads Overrides Sub F(ByVal aC3 As C3)
Debug.WriteLine("F(c3)", "C3")
End Sub

End Class
FWIW: Rather then overloading function F, I normally give each a distinct
name, something like:

Public MustInherit Class C

Public MustOverride Sub F(ByVal aC As C)
Public MustOverride Sub FC1(ByVal aC1 As C1)
Public MustOverride Sub FC2(ByVal aC2 As C2)
Public MustOverride Sub FC3(ByVal aC3 As C3)

End Class

If don't want the "reversal" of the parameters you can make F a template
method. Something like:

Public MustInherit Class C

Public Sub F(ByVal aC As C)
aC.FC(Me)
End Sub

Public MustOverride Sub FC(ByVal aC As C)
Public MustOverride Sub FC1(ByVal aC1 As C1)
Public MustOverride Sub FC2(ByVal aC2 As C2)
Public MustOverride Sub FC3(ByVal aC3 As C3)

End Class

Hope this helps
Jay

"Philip Warner" <Ph**********@discussions.microsoft.com> wrote in message
news:CC**********************************@microsof t.com...
I have a set of classes:

C (base)
C1 (inherits C)
C2 (inherits C)
...
Cn (inherits C)

(the C1..Cn also have subclasses, but thats not really relevant to the
question)

C has the following functions:

F(C) (implemented in C)
F(C1) (mustoverride)
...
F(Cn) (mustoverride)

When I declare two variables (x, y) of type C, and call x.F(y), it calls
the
base class implementation of F(C) which is quite understandable. However,
I
would like to actually call the appropriate F(Cn) based on the actual
classes
of x & y.

What is the best way of doing this?

Currently I have a case statement inside F(C), which is (a) bad for
maintenance and (b) a kludge.

Nov 21 '05 #4
> 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.

Nov 21 '05 #5
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.

Nov 21 '05 #6
> I'm sure you could kludge together something with Reflection. However I have
to ask why?
Ignorance?

Using Reflection I'm certain would be more fragile, and perform
significantly worse
Then I'll avoid it.

However! I recommend Double Dispatch as it is a rather common OO method to
solve the problem you seem to be stating.
It what I have currently (badly) implemented (after I gave up on the case
statement); I made the mistake of thinking I needed to implement n Fc's,
rather than 1 Fc and n Fc1's...if that makes sense. Much happier now.

Why do you think there are twice as many as you need?
In this case, fuzzy thinking...it was late at night...the dog ate my homework.

Unfortunately I am not seeing any really good links on double dispatch.


No problem; I'll use double-dispatching, especially now that I have an
official-sounding name for it.

Thanks for you extremely helpful replies.
Nov 21 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Bill Menees | last post by:
I've got a RichTextBoxEx inherited from RichTextBox, and I want to overload the TextLength property to use TextBoxBase's implementation of TextLength. But since TextBoxBase isn't my immediate base...
8
by: TS | last post by:
I am trying to get set a property of a control on the inherited class from base class. I imagine i have to use reflection, so could someone give me the code to do it? something like this?...
3
by: Janaka | last post by:
When using object inheritance is it possible to call a method of the base class more than 1 object below the inherited class? For example, assume that the Labrador class inherits all the way down...
4
by: ad | last post by:
base only can call the parent 's method The result of the example below is I am Parent I am Child How can we call the grandparent's method in a inhreited class, I want the result is I am...
5
by: wrecker | last post by:
Hi all, I have a few common methods that I need to use at different points in my web application. I'm wondering where the best place would be to put these? I think that I have three options. ...
10
by: Chad Miller | last post by:
I currently have a base form that I inherit. The base for has a custom event. The event will not raise threw the inherited form. I was wondering if events work threw inheritance or should I use...
3
by: John A. Prejean | last post by:
This one has me stumped. I have a base form I am trying to wrap up, but I have one problem. In two functions I am opening a "record detail" form. I would like to keep the code in the base form...
6
by: roland.bali | last post by:
Hi, Here is the basic setup, my base class is Shoe which has a child class called Sandal. I would like to create objects by calling Sandal.Load. But without overloading Load in Sandal and...
4
by: Alan T | last post by:
I got a method in my ancestor form declared as Protected, this method has empty body. In my descendant form I declared as Protected also, then compile has no problem but the name of the method has...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.