使用字符串名调用属性或方法 (Visual Basic)
在大多数情况下,你可以在设计时发现对象的属性和方法,并编写代码来对其进行处理。 但在某些情况下,你可能事先并不知道对象的属性和方法,或者只是希望最终用户能够在运行时灵活指定属性或执行方法。
CallByName 函数
例如,假设某个客户端应用程序通过将运算符传递给 COM 组件来计算用户输入的表达式。 你不断地向该组件添加需要新运算符的新函数。 在使用标准对象访问方法时,必须重新编译并重新分发该客户端应用程序,这样它才能使用新运算符。 为了避免这种情况,可以使用 CallByName
函数将新运算符作为字符串传递,而无需更改应用程序。
CallByName
函数允许在运行时使用字符串指定属性或方法。 CallByName
函数的签名如下所示:
Result = 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
用于输入函数的名称,则你可以使用以下代码对 TextBox1
中的表达式调用 SquareRoot
函数:
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
可能会对性能造成严重影响。