文字列名によるプロパティまたはメソッドの呼び出し (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 を使用するとパフォーマンスに著しい負荷がかかる可能性があります。

関連項目