Visual Basic 6 свойство по умолчанию для встроенных функций - PullRequest
1 голос
/ 01 сентября 2009

Visual Basic имеет свойства по умолчанию, которые иногда неявно вызываются при оценке выражения. Тем не менее, я, кажется, столкнулся с несоответствием с этим неявным выполнением свойств по умолчанию. Макет проекта выглядит так:

Class1:

property test -> class2 (default)

Class2:

property test -> string "hello world" (default)

Form1:

Dim x As New Class2
MsgBox x
Debug.Print x

Оператор MsgBox будет неявно вызывать значение по умолчанию для x (будучи тестируемым для класса 1), и, более того, он будет вызывать значение по умолчанию для этого (будучи тестируемым для класса 2), в результате чего на экране будет отображаться «привет мир». Однако оператор Debug.Print этого не делает, и, следуя отладчику, можно увидеть, что вызывается только первое значение по умолчанию (для class1).

Я проверил, что многие из встроенных функций, таких как MsgBox / RTrim / LTrim, демонстрируют такое поведение, и что любые написанные самостоятельно методы или методы класса не делают этого; но я не могу понять, почему это происходит?

1 Ответ

4 голосов
/ 01 сентября 2009

Это вовсе не «поведение» встроенных функций, а зависит от того, как COM преобразует ссылки на объекты и их варианты в строки. Это также связано с ключевыми словами языка Set and Let и оценкой выражений, особенно в скобках. Рассмотрим этот пример кода:

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

Обратите внимание, что приведение ссылки на объект к строке является ошибкой во время компиляции (вызов CStr (x)), в то время как вариант, содержащий ссылку (IDispatch один), приведен просто отлично (s = v). Последнее назначение «развернет» свойства по умолчанию настолько глубоко, насколько это необходимо, в то время как свойство по умолчанию оценивается как IDispatch (вызов Invoke с DISPID, установленным в -1).

Вкратце: если у вас есть ссылка на объект и вам необходимо рекурсивно оценивать свойства по умолчанию для значения типа «примитив» (например, строки), используйте CStr (CVar (x)) (или CInt (CVar ... ) и т. д.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...