Reputation: 13
I'm converting a VB6 project to Vb.net.
I have 10+ forms that all have a sub like this:
Public sub DoSomething()
*doing stuff here
end sub
And I have a main form that call the other forms' sub
private sub TouchForm(frmRef as form)
dim FormPublic as Form
set FormPublic = frmRef
FormPublic.Show
FormPublic.DoSomething()
End Sub
I got an error on FormPublic.DoSomething() is not a member of 'System.Windows.Forms.Form' when I'm trying to do it in Vb.net.
Upvotes: 1
Views: 582
Reputation: 1892
You must try something like this:
private sub TouchForm(frmRef as form)
dim FormPublic as Form = New frmRef
FormPublic.Show
FormPublic.DoSomething()
End Sub
Upvotes: 0
Reputation: 43743
In .NET, the compiler checks the variable types to ensure that you only ever call members that actually exist. This type-checking is a compile-time safety feature which many people prefer, since it avoids unnecessary run-time errors due to accidental usage of unsupported members.
However, to keep VB.NET as backwards-compatible with VB6 as possible, Microsoft added a new option. Just like VB6 had Option Explicit
to allow it to be backwards-compatible with older versions which did not require variable declarations, VB.NET adds a new Option Strict
.
When you turn Option Strict Off
, it disables that compiler type-checking feature so that VB6-style late-binding is allowed. However, it's not quite a perfect match. Even with Option Strict Off
, the late-binding syntax is only allowed on Object
type variables. Therefore, in order to call an un-checked member, you need to do so by first casting the object to the Object
type. For instance:
Option Strict Off
Private Sub TouchForm(frmRef As form)
Dim FormPublic As Object
FormPublic = frmRef
FormPublic.Show
FormPublic.DoSomething()
End Sub
Or, more simply:
Option Strict Off
Private Sub TouchForm(frmRef As Object)
frmRef.Show
frmRef.DoSomething()
End Sub
However, as Maximilian said in the comments above, in most cases, it's better to leave Option Strict On
so that you can retain that valuable type-checking. As he mentioned, the most obvious way to accomplish this, while still keeping Option Strict On
, is to have all of the forms implement a common interface, like this:
Public Interface ISomeInterface
Sub Show()
Sub DoSomething()
End Interface
Private Sub TouchForm(frmRef As ISomeInterface)
frmRef.Show
frmRef.DoSomething()
End Sub
When you do it that way, the compiler will only allow you to call the TouchForm
method if you pass in an object that implements that particular interface. You would therefore need to implement that interface in all of the Form
classes which support those features. If you try to call it and pass it a form that does not implement that interface, it will fail to compile.
If interfaces are not appropriate, some other options for accomplishing the same thing would be the use of a base class, or delegates. If none of those things are possible, and you have to call it late-bound, but you still want to leave Option Strict On
, you can still do so through the use of reflection:
Private Sub TouchForm(frmRef As Form)
frmRef.Show
frmRef..GetType().GetMethod("DoSomething").Invoke(frmRef, {})
End Sub
Turning Option Strict Off
is not always a bad choice. It's such a useful feature, that it was actually added to C# via it's dynamic
keyword. However, in VB, there is no way to do it on a variable-by-variable basis, so it's not as flexible. In VB, you can only turn Option Strict Off
for an entire file. So when you do, none of the code in that file is type-checked. So, in my opinion, when you do turn if off, it's best to keep it on as few files as possible and keep the files as short as possible. You may even want to consider implementing it as a Partial Class
so that only that one method of the class is in the unchecked file while the rest of the code is in another file which is type-checked.
Upvotes: 3