2009-09-01 28 views
1

Visual Basic具有在評估表達式時有時隱式調用的默認屬性。但是,我似乎遇到了這種隱式執行默認屬性的差異。該項目的佈局是這樣的:Visual Basic 6內置函數的默認屬性

的Class1:

property test -> class2 (default) 

等級2:

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

Form1中:

Dim x As New Class2 
MsgBox x 
Debug.Print x 

MsgBox語句將默認調用x的默認值(在class1上測試),並進一步調用默認值(在class2上測試),這會導致屏幕上顯示「hello world」。但是,Debug.Print語句不會執行此操作,並且通過跟隨調試程序,可以看到只有第一個默認值(在class1上)被調用。

我已經驗證了許多內置函數(如MsgBox/RTrim/LTrim)表現出這種行爲,並且任何自寫的方法或類方法都不會執行此操作;但我無法弄清楚爲什麼會發生這種情況?

回答

4

這不是內建函數的「行爲」,而是取決於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 

通知鑄造對象引用字符串是如何而含有的引用(一個IDispatch一個)的變體澆鑄就好編譯時誤差(CSTR中(x)的呼叫)( s = v)。這個最後的賦值將默認屬性「展開」爲默認屬性,而默認屬性評估爲IDispatch(調用DISPID設置爲-1的Invoke)。簡而言之:如果你有一個對象的引用,並且需要評估默認屬性,以recusively值爲「primitive」數據類型(例如字符串),則使用CStr(CVar(x))(或CInt(CVar ..) 。)等)