文字列名によるプロパティまたはメソッドの呼び出し (Visual Basic)
オブジェクトのプロパティやメソッドは、デザイン時に把握して、これらを処理するコードを作成できることがほとんどです。 しかし、オブジェクトのプロパティやメソッドを事前に知ることができない場合や、実行時にエンド ユーザーがプロパティを指定したりメソッドを実行したりできる柔軟性を持たせたい場合があります。
CallByName 関数
例として、COM コンポーネントにユーザーが演算子を渡すことで入力した式を評価する、クライアント アプリケーションを考えます。 ここでは、新しい演算子が必要な新しい関数を、継続的にコンポーネントに追加するものとします。 標準的なオブジェクトへのアクセス手法を使用する場合、新しい演算子を使用するには、クライアント アプリケーションを再コンパイルして配布し直す必要があります。 これは、CallByName
関数を使用して新しい演算子を文字列として渡すことで回避できます。アプリケーションを変更する必要はありません。
CallByName
関数を使用すると、文字列を使用して実行時にプロパティまたはメソッドを指定することができます。 CallByName
関数のシグネチャは次のようになります。
Result = CallByName
(<オブジェクト>, <プロシージャ名>, <呼び出しの型>, <引数>())
最初の引数である <オブジェクト> は、処理対象のオブジェクトの名前を取ります。 <プロシージャ名> 引数は、呼び出すメソッドまたはプロパティのプロシージャ名を含んだ文字列を取ります。 <呼び出しの型> 引数は、メソッド (Microsoft.VisualBasic.CallType.Method
)、読み取り対象のプロパティ (Microsoft.VisualBasic.CallType.Get
)、設定対象のプロパティ (Microsoft.VisualBasic.CallType.Set
) のいずれかのうち、呼び出すプロシージャの型を表す定数を取ります。 <引数> 引数は省略可能であり、プロシージャに渡す引数が含まれる Object
型の配列を取ります。
CallByName
は、現在のソリューションのクラスと共に使用できますが、多くの場合は、COM オブジェクトまたは .NET Framework アセンブリのオブジェクトにアクセスするために使用します。
次のコードに示すように、SquareRoot
という名前の新しい関数を持つ、MathClass
という名前のクラスが含まれるアセンブリへの参照を追加するとします。
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
を使用するときには、こうしたエラーやその他のエラーも考慮して、堅牢なエラー処理コードを追加する必要があります。
Note
CallByName
関数は便利な場合もありますが、その有用性をパフォーマンスに対する影響と比較して考慮するようにしてください。CallByName
を使用してプロシージャを呼び出すと、遅延バインディング呼び出しに比べてやや時間がかかります。 ループ内など、繰り返し呼び出される関数を呼び出す場合、CallByName
を使用するとパフォーマンスに著しい負荷がかかる可能性があります。
関連項目
.NET