在大部分情況下,您可以在設計時間探索對象的屬性和方法,並撰寫程式代碼來處理它們。 不過,在某些情況下,您可能事先不知道對象的屬性和方法,或者您可能只想讓終端使用者在運行時間指定屬性或執行方法的彈性。
CallByName 函式
例如,假設用戶端應用程式會藉由將運算元傳遞至 COM 元件來評估使用者輸入的表達式。 假設您不斷將新函式新增至需要新運算子的元件。 當您使用標準物件存取技術時,您必須先重新編譯和轉散發用戶端應用程式,才能使用新的運算符。 若要避免這種情況,您可以使用 函 CallByName 式將新的運算符當做字串傳遞,而不需變更應用程式。
函 CallByName 式可讓您在執行時間使用字串來指定屬性或方法。 函式的 CallByName 簽章如下所示:
結果 = CallByName(Object, ProcedureName, CallType, Arguments())
第一個自變數 Object 會採用您想要採取行動的物件名稱。
ProcedureName 自變數會接受包含要叫用之方法或屬性程式名稱的字串。
CallType 自變數會接受常數,代表要叫用的程式類型:方法(Microsoft.VisualBasic.CallType.Method)、屬性讀取 (Microsoft.VisualBasic.CallType.Get), 或屬性集 (Microsoft.VisualBasic.CallType.Set)。
Arguments 參數是選擇性的,它接受類型為Object的數組,其中包含程序的任何參數。
您可以在目前的方案中搭配類別使用 CallByName,但最常用來存取 COM 物件或 .NET Framework 程式集中的物件。
假設您將一個參考新增到包含類別名為 MathClass 的元件中,該類別具有一個新函式,名為 SquareRoot,如下列程式代碼所示:
Class MathClass
Function SquareRoot(ByVal X As Double) As Double
Return Math.Sqrt(X)
End Function
Function InverseSine(ByVal X As Double) As Double
Return Math.Atan(X / Math.Sqrt(-X * X + 1))
End Function
Function Acos(ByVal X As Double) As Double
Return Math.Atan(-X / Math.Sqrt(-X * X + 1)) + 2 * Math.Atan(1)
End Function
End Class
您的應用程式可以使用文字方塊控制項來控制將呼叫的方法及其參數。 例如,如果TextBox1包含要評估的表達式,並且TextBox2用來輸入函式的名稱,您可以使用下列程式代碼在SquareRoot中的運算式上呼叫TextBox1函式:
Private Sub CallMath()
Dim Math As New MathClass
Me.TextBox1.Text = CStr(CallByName(Math, Me.TextBox2.Text,
Microsoft.VisualBasic.CallType.Method, TextBox1.Text))
End Sub
如果您在TextBox1輸入「64」,在TextBox2輸入「SquareRoot」,然後呼叫CallMath程序,則會評估TextBox1中的數字的平方根。 範例中的程式碼會叫用 SquareRoot 函式(其接受包含要評估之表達式的字串作為必要參數),並在 TextBox1 中傳回「8」(64 的平方根)。 當然,如果使用者在 中 TextBox2輸入無效的字串,如果字串包含屬性的名稱而非方法,或方法有額外的必要自變數,則會發生運行時錯誤。 當您使用 CallByName 來預期這些或任何其他錯誤時,您必須加入強健的錯誤處理程式碼。
備註
CallByName函式雖然在某些情況下可能很有用,但您必須權衡其效用與效能影響 —使用 CallByName 來呼叫程序比晚期綁定呼叫稍微慢一點。 如果您要叫用重複呼叫的函式,例如循環內部, CallByName 可能會對效能產生嚴重影響。