ほとんどの場合、デザイン時にオブジェクトのプロパティとメソッドを検出し、それらを処理するコードを記述できます。 ただし、場合によっては、オブジェクトのプロパティとメソッドについて事前に把握していない場合や、実行時にエンド ユーザーがプロパティを指定したりメソッドを実行したりする柔軟性が必要な場合があります。
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
を使用できますが、ほとんどの場合、.NET Framework アセンブリから COM オブジェクトまたはオブジェクトにアクセスするために使用されます。
次のコードに示すように、 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
はパフォーマンスに重大な影響を与える可能性があります。
こちらも参照ください
.NET