Reputation: 1799
Visual Basic has default properties that are sometimes implicitly called when evaluating an expression. However, I seem to of come across a discrepancy with this implicit execution of default properties. The project layout looks like:
Class1:
property test -> class2 (default)
Class2:
property test -> string "hello world" (default)
Form1:
Dim x As New Class2
MsgBox x
Debug.Print x
The MsgBox statement will implicitly call x's default (being test on class1) and further more it will call the default on that (being test on class2) which results in "hello world" being displayed on the screen. The Debug.Print statement does not do this however, and by following the debugger, it can be seen that only the first default (on class1) is being called.
I have verified that many of the built in functions such as MsgBox/RTrim/LTrim exhibit this behaviour, and that any self written methods or class methods do not do this; but am unable to work out why this occurs?
Upvotes: 2
Views: 1084
Reputation: 11991
This is not a "behaviour" of the built-in functions at all, but depends on the way COM does converting object references and variants to strings. This also has a connection with Set and Let language keywords and expression evaluation, especially parentheses. Consider this sample code:
Private Sub Form_Load()
Dim x As Class1
Dim v As Variant
Dim s As String
Set x = New Class1
Set v = x ' None
Let v = x ' Once
Set v = (x) ' Once
Let v = (x) ' Twice
's = x ' Compile error: Type mismatch
Set v = x
s = v ' Twice
s = CVar(x) ' Twice
MsgBox x
'Debug.Print CStr(x) ' Compile error: Type mismatch
'Debug.Print CVar(x) ' Run-time error: Type mismatch
Debug.Print CStr(CVar(x)) ' Twice
pvTest1 x
End Sub
Private Function pvTest1(ByVal o As Variant)
'Debug.Print o ' Run-time error: Type mismatch
Debug.Print CStr(o) ' Twice
End Function
Notice how casting object reference to a string is a compile-time error (the CStr(x) call) while a variant containing a reference (an IDispatch one) is cast just fine (s = v). This last assignment will "unfold" default properties as deep as it takes while the default propery evaluates to an IDispatch (calling Invoke with DISPID set to -1).
In short: if you have a reference to an object and need to evaluate default properties recusively to a value of "primitive" data type (e.g. string) use CStr(CVar(x)) (or CInt(CVar...), etc)
Upvotes: 5