大多数情况下,您可以在设计时发现对象的属性和方法,并且编写代码以处理它们。但是,在少数情况下,您可能不知道某个对象的一些高级属性和方法,或者,您可能只是想要这种灵活性,即允许最终用户在运行时指定属性或执行方法。
例如,请考虑下面的情况,某个客户端应用程序,它通过传递一个运算符到服务器程序来计算由用户输入的表达式。现在,假定您要经常性地向需要新运算符的服务器添加新函数。那么,不幸的是,在客户端应用程序能够使用新的运算符之前,您需要重新编辑和重新发布它。为了避免这种情况,可以使用 CallByName 函数把新运算符当作字符串来传递,而不需要更改应用程序。
CallByName 函数允许您使用一个字符串在运行时指定一个属性或方法。CallByName 函数的用法如下:
Result = CallByName(Object, ProcedureName, CallType, Arguments())
CallByName 的第一个参数包含要对其执行动作的对象名。第二个参数,ProcedureName,是一个字符串,包含将要调用的方法或属性过程名。CallType 参数包含一个常数,代表要调用的过程的类型:方法 (vbMethod)、property let (vbLet)、property get (vbGet),或 property set (vbSet)。最后一个参数是可选的,它包含一个变量数组,数组中包含该过程的参数。
假定您有一个服务器应用程序,MathServer,并且它具有一个新的函数 SquareRoot。该应用程序中有两个 TextBox 控件:Text1 包含要计算的表达式;Text2 用于输入该函数的名称。要对 Text1 中的表达式调用 SquareRoot 函数,您可以在一个命令按钮的 Click 事件中使用下面的代码:
Private Sub Command1_Click()
Text1.Text = CallByName(MathServer, Text2.Text, vbMethod, Text1.Text)
End Sub
如果用户在 Text1 中输入 "64 / 4",在 Text 2 中输入 "SquareRoot",则上面的代码将调用 SquareRoot 函数(要求一个必需的参数,它是一个包含将要计算的表达式的字符串),并且在 Text1 中返回 "4" (16 或64/4的平方根)。当然,如果用户在 Text2 中输入了一个无效的字符串,或者该字符串包含一个属性名而不是方法名,或者该方法要求附加的必需的参数,那么将会产生一个运行时错误。可以猜到,当您使用 CallByName 来预处理这些或其他的错误时,需要添加强健的错误处理程序代码。
尽管 CallByName 函数在某些情况下可能很有用,但是,还是需要在衡量其实用性时考虑对性能可能的影响 — 同后期绑定相比,使用 CallByName 来调用一个过程只会稍稍慢一点儿。如果您正调用的函数将要被重复调用很多次,例如在一个循环内部,则 CallByName 将会对性能产生严重的影响。