2

Visual Basic には、式を評価するときに暗黙的に呼び出されることがある既定のプロパティがあります。ただし、このデフォルト プロパティの暗黙的な実行には矛盾があるようです。プロジェクトのレイアウトは次のようになります。

クラス1:

property test -> class2 (default)

クラス 2:

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

フォーム1:

Dim x As New Class2
MsgBox x
Debug.Print x

MsgBox ステートメントは暗黙的に x のデフォルト (class1 のテスト) を呼び出し、さらにそのデフォルト (class2 のテスト) を呼び出します。その結果、画面に「hello world」が表示されます。ただし、Debug.Print ステートメントはこれを行いません。デバッガーをたどると、(class1 の) 最初のデフォルトのみが呼び出されていることがわかります。

MsgBox/RTrim/LTrim などの組み込み関数の多くがこの動作を示すこと、および自己記述メソッドまたはクラス メソッドがこれを行わないことを確認しました。しかし、なぜこれが起こるのか分かりませんか?

4

1 に答える 1

5

これは組み込み関数の「動作」ではありませんが、COM がオブジェクト参照とバリアントを文字列に変換する方法に依存します。これは、Set および 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 に評価される間 (DISPID を -1 に設定して Invoke を呼び出します)、既定のプロパティをできるだけ深く "展開" します。

要するに、オブジェクトへの参照があり、デフォルトのプロパティを再帰的に「プリミティブ」データ型 (文字列など) の値に評価する必要がある場合は、CStr(CVar(x)) (または CInt(CVar...) などを使用) を使用します。 )

于 2009-09-01T19:27:27.703 に答える