ByRef and Implicit Conversions

E

Earthlink

This is best explained by looking at the comments in the sample code below.
Is this a VB.NET bug?

Option Strict On

Public Class Class1

End Class

Public Class Class2 : Inherits Class1

Public Sub bar()
Dim c3 As New Class3

Dim c2 As Class2
c3.foo(c2) '*** Compiler Error: Option Strict On disallows implicit
conversions from 'ClassLibrary1.Class1' to 'ClassLibrary1.Class2'

c3.foo(Me) 'However, this is OK even though Me is an instance of
Class 2

c3.foo(CType(c2, Class2)) '?? This also OK, even though I am also
passing in an instance of Class 2

Dim c1 As Class1
c3.foo(c1) 'This is OK - no surprise
End Sub

End Class

Public Class Class3

Public Sub foo(ByRef arg1 As Class1)
End Sub

End Class
 
S

Scott M.

You say it's ok "even though this is an instance". It isn't that having an
instance is somehow an exception to the rule, it is the rule. The only time
you are encountering a problem is when you are trying to pass a type (not an
instance). You need to pass instances.
 
D

David

This is best explained by looking at the comments in the sample code below.
Is this a VB.NET bug?

It's confusing, but I don't see it as a bug, just a flaw :). I'm not
sure if I can come up with language that would make it clearer, but to
my mind the thing to consider is the ByRef parameters are very concerned
with the variable declaration in the caller.
Option Strict On

Public Class Class1

End Class

Public Class Class2 : Inherits Class1

Public Sub bar()
Dim c3 As New Class3

Dim c2 As Class2
c3.foo(c2) '*** Compiler Error: Option Strict On disallows implicit
conversions from 'ClassLibrary1.Class1' to 'ClassLibrary1.Class2'

Presumably you see why, right? If this were allowed, then "foo" could
set c2 to an instance of Class1, and that can never be allowed. Make
sure you understand this clearly or the rest of the examples won't make
sense.
c3.foo(Me) 'However, this is OK even though Me is an instance of Class 2

Forget "instance" in this case, consider declared variable. In this
case, you don't have a declared variable. "Me" is a keyword whose instance
will never change. In other words, ByRef has no effect here, "foo" can
only assign to a temporary Class1 variable, and that's fine.

The problem we saw in the first example can't happen here, so VB.Net
allows it.
c3.foo(CType(c2, Class2)) '?? This also OK, even though I am also
passing in an instance of Class 2

And a similar thing here. CType(c2, Class2) isn't an lvalue; it doesn't
refer to a variable name in the caller, so nothing untoward can happen
with an assignment in "foo".

Put another way, VB.Net creates a temporary variable to hold the results
of CType(c2,class2), and then sends that temporary variable to "foo".
foo can change what the temporary points to, but can't change what c2
points to, so VB.Net allows it.

Dim c1 As Class1
c3.foo(c1) 'This is OK - no surprise
End Sub

End Class

Public Class Class3

Public Sub foo(ByRef arg1 As Class1)
End Sub

End Class

I'm honestly not sure if this explanation will help at all, so ask again
if there's something confusing.

BTW, the real confusion here is that VB.Net allows non-lvalues to sent
as ByRef parameters. This helps nothing of course and is a prime source
for some very tricky bugs, but I suppose the thinking is that it makes
things a tad easier for beginners.
 
E

Ed Johnson

The "If this were allowed ..." sentence makes it crystal clear even if I
were not to read anything else. Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top