470,581 Members | 2,460 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,581 developers. It's quick & easy.

how to do late binding with Option Explicit On

Sam
Hi,
Here's my class's constructor:

Public Sub New(ByVal frmParent As Form, ByVal curRow As Integer)
MyBase.New()
End Sub

I have a member variable that I want to initialize with frmParent. Then
I would call methods on it. The issue is that frmParent can be any form
of my applications and therefore I have to do:

Directcast(myMemberVar,FormA).MethodOfFormA

DirectCast(myMemberVar, FormB).MethodOfFormB

How can I avoid doing this ?? How can I simply set the type of my
member variable to the type of frmParent ?

Thx

Nov 21 '05 #1
7 1461
Sam
I meant Option Strict On, not Option Explicit On.... sorry about that !

Nov 21 '05 #2
"Sam" <sa**************@voila.fr> schrieb:
Here's my class's constructor:

Public Sub New(ByVal frmParent As Form, ByVal curRow As Integer)
MyBase.New()
End Sub

I have a member variable that I want to initialize with frmParent. Then
I would call methods on it. The issue is that frmParent can be any form
of my applications and therefore I have to do:

Directcast(myMemberVar,FormA).MethodOfFormA

DirectCast(myMemberVar, FormB).MethodOfFormB


Do the methods have different names? I assume they should have the same
name:

\\\
Public Class BaseForm
Inherits Form

End Class

Public Class FormA
Inherits BaseForm

Public Sub Foo()
MsgBox("'FormA.Foo'")
End Sub
End Class

Public Class FormB
Inherits BaseForm

Public Sub Foo()
MsgBox("'FormB.Foo'")
End Sub
End Class
///

Usage:

\\\

' Use VB.NET's handy 'CallByName' function.
Public Sub Test1(ByVal Form As BaseForm)
CallByName(Form, "Foo", CallType.Method.Method)
End Sub

' Use .NET's reflection.
Public Sub Test2(ByVal Form As BaseForm)
Form.GetType().InvokeMember( _
"Foo", _
BindingFlags.Instance Or BindingFlags.InvokeMethod Or
BindingFlags.Public, _
Nothing, _
Form, _
Nothing _
)
End Sub
///

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>

Nov 21 '05 #3
Sam
No, they do have different name and they are not related at all. THey
do completely different things.

Nov 21 '05 #4
"Sam" <sa**************@voila.fr> schrieb:
No, they do have different name and they are not related at all. THey
do completely different things.


Mhm... Then I am curious why you do not use 'DirectCast'...

--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>
Nov 21 '05 #5


Even with totally unrelated functions / forms the Herfried's reflection
example above works fine, so that hopefully answers your original
question.

I am curious though as to how the class knows which function(s) to call
on the form.

By using late binding we avoid having to declare the form's runtime
type at design time but seem to buy an amount of runtime complication
e.g.

class Form1
inherits System.Windows.Forms.Form
...
public sub foo()
' do something
end sub

end class

class Form2
inherits System.Windows.Forms.Form
...
public sub bar()
' do something else
end sub

end class
class Controller '??

public sub new ( frm as System.Windows.Forms.Form, rowVal as
integer )
_form = frm
_row = rowVal
end sub

public sub DoSomething()

' at this point, how do we know which function we are trying to
invoke on the form

end sub

end class
What is the general shape of the program on which you are working?

Alan.

Nov 21 '05 #6
Same,
In addition to the other comments:

How do you know to call FormA.MethodOfFormA verses FormB.MethodOfFormB?

I would use Polymorphism to know which to call. Remember that Polymorphism
is one of the major tenants of OO.

In order to use Polymorphism each form would have the "same" method to call,
such as frmParent.SomeMethod. Where FormA & FormB would offer their own
implementation of SomeMethod. In other words FormA.SomeMethod does something
specific to FormA, while FormB.SomeMethod does something specific to FormB.
However SomeMethod has some common expected behavior, such as Save Record.

CallByName would be useful if you know the specific name, but you cannot
require a base class or interface. I would consider using a Custom Attribute
to identify the method that needs to be called, using Reflection to find the
method with the attribute, & then using Reflection to invoke the method.
However there may be performance considerations to consider with either
CallByName or Reflection.
Here are examples of using either a base class or an Interface to define
SomeMethod.

Something like:

Public Class BaseForm
Inherits System.Windows.Forms.Form

Public Overridable Sub SomeMethod()
End Sub

End Class

Public Class FormA
Inherits BaseForm

Public Overrides Sub SomeMethod()
' Code specific to FormA
End Sub

End Class

Public Class FormB
Inherits BaseForm

Public Overrides Sub SomeMethod()
' Code specific to FormB
End Sub

End Class

| Public Sub New(ByVal frmParent As BaseForm, ByVal curRow As Integer)
| MyBase.New()
frmParent.SomeMethod()
| End Sub
Alternatively you can use Interfaces:
Public Interface ISomeMethodable

Sub SomeMethod()

End Interface

Public Class FormA
Inherits System.Windows.Forms.Form
Implements ISomeMethodable

Public Sub MethodOfFormA() Implements ISomeMethodable.SomeMethod
' Code specific to FormA
End Sub

End Class

Public Class FormB
Inherits System.Windows.Forms.Form
Implements ISomeMethodable

Public Sub MethodOfFormB() Implements ISomeMethodable.SomeMethod
' Code specific to FormB
End Sub

End Class

| Public Sub New(ByVal frmParent As ISomeMethodable, ByVal curRow As
Integer)
| MyBase.New()
frmParent.SomeMethod()
| End Sub

In either case (base class or interface) you can simply pass an instance of
FormA or FormB to the constructor:

Dim a As FormA
Dim b As FormB

Dim c As New SomeObject(a, 0)
Dim d As New SomeObject(b, 0)
The advantage of the BaseForm is that you know frmParent is still a Form.

The advantage of ISomeMethodable is that any Type can implement the
interface, it may not be a Form, however each implementer can have its own
name for the implemented method.

Of course you can do something like:

| Public Sub New(ByVal frmParent As Form, ByVal curRow As Integer)
| MyBase.New()
If TypeOf frmParent Is ISomeMethodable Then
Dim callee As ISomeMethodable = DirectCast(frmParent,
ISomeMethodable)
callee.SomeMethod()
End If
| End Sub

Which allows your constructor to still require a Form, however it will call
SomeMethod for those objects that implement ISomeMethodable...
Hope this helps
Jay
"Sam" <sa**************@voila.fr> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
| Hi,
| Here's my class's constructor:
|
| Public Sub New(ByVal frmParent As Form, ByVal curRow As Integer)
| MyBase.New()
| End Sub
|
| I have a member variable that I want to initialize with frmParent. Then
| I would call methods on it. The issue is that frmParent can be any form
| of my applications and therefore I have to do:
|
| Directcast(myMemberVar,FormA).MethodOfFormA
|
| DirectCast(myMemberVar, FormB).MethodOfFormB
|
| How can I avoid doing this ?? How can I simply set the type of my
| member variable to the type of frmParent ?
|
| Thx
|
Nov 21 '05 #7
Sam,
Here's an example of using a CustomAttribute & Reflection to invoke the
method:

<AttributeUsage(AttributeTargets.Method)> _
Public Class SomeMethodAttribute
Inherits Attribute

End Class

Public Class FormA
Inherits System.Windows.Forms.Form

<SomeMethod()> _
Public Sub MethodOfFormA()
' Code specific to FormA
Debug.WriteLine("MethodOfFormA", "FormA")
End Sub

End Class

Public Class FormB
Inherits System.Windows.Forms.Form

<SomeMethod()> _
Public Sub MethodOfFormB()
' Code specific to FormB
Debug.WriteLine("MethodOfFormB", "FormB")
End Sub

End Class

Public Sub New(ByVal frmParent As Form, ByVal curRow As Integer)
MyBase.New()

Dim theType As Type = frmParent.GetType()
For Each method As System.Reflection.MethodInfo In
theType.GetMethods()
Dim theAttributes() As Attribute =
DirectCast(method.GetCustomAttributes(GetType(Some MethodAttribute), False),
Attribute())
If theAttributes.Length > 0 Then
method.Invoke(frmParent, Nothing)
End If
Next

End Sub

NOTE: The above code will invoke *all* the methods in frmParent that have
the SomeMethodAttribute on them.

The advantage of using the above is that it allows the caller to only know
about the SomeMethodAttribute, and avoids coupling to each specific Form
type.

Hope this helps
Jay

"Sam" <sa**************@voila.fr> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
| Hi,
| Here's my class's constructor:
|
| Public Sub New(ByVal frmParent As Form, ByVal curRow As Integer)
| MyBase.New()
| End Sub
|
| I have a member variable that I want to initialize with frmParent. Then
| I would call methods on it. The issue is that frmParent can be any form
| of my applications and therefore I have to do:
|
| Directcast(myMemberVar,FormA).MethodOfFormA
|
| DirectCast(myMemberVar, FormB).MethodOfFormB
|
| How can I avoid doing this ?? How can I simply set the type of my
| member variable to the type of frmParent ?
|
| Thx
|
Nov 21 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

9 posts views Thread by Scott English | last post: by
5 posts views Thread by eBob.com | last post: by
30 posts views Thread by lgbjr | last post: by
8 posts views Thread by Boni | last post: by
3 posts views Thread by gregory_may | last post: by
14 posts views Thread by Siv | last post: by
1 post views Thread by livre | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.