Visual Basic における変数のトラブルシューティング
更新 : 2007 年 11 月
ここでは、Visual Basic で変数を使用する際に起きる一般的な問題についていくつか説明します。
オブジェクトのメンバにアクセスできない
オブジェクトのプロパティまたはメソッドにアクセスしようとする場合、発生するエラーには 2 つの種類があります。
オブジェクト変数を特定のデータ型で宣言した後で、その型で定義していないメンバを参照するためにその変数を使うと、コンパイラからエラー メッセージが生成されることがあります。
オブジェクト変数に代入したオブジェクトが、コードからアクセスしようとしたメンバを公開していない場合、ランタイム MemberAccessException が発生します。オブジェクト型 (Object) の変数の場合、メンバが Public でない場合にもこの例外が発生します。原因は、遅延バインディングでアクセスできるのは Public メンバだけだからです。
Option Strict ステートメント が On になっている場合、オブジェクト変数がアクセスできるのは、その変数の宣言時に指定したクラスのメソッドとプロパティだけです。次に例を示します。
Option Strict On
Dim p As Object = New System.Windows.Forms.Label
Dim q As System.Windows.Forms.Label = New System.Windows.Forms.Label
Dim j, k As Integer
' The following statement generates a compiler error.
j = p.Left
' The following statement retrieves the left edge of the label
' in pixels.
k = q.Left
この例の場合、p で使用できるのは Object クラス自身のメンバだけです。Left プロパティは含まれません。一方、q は、Label 型として宣言されているので、System.Windows.Forms 名前空間の Label クラスのすべてのメソッドとプロパティを使用できます。
修正方法
特定のクラスのオブジェクトにあるすべてのメンバにアクセスできるようにするには、できる限りオブジェクト変数をそのクラスの型で宣言します。オブジェクト型がコンパイル時にわからないなどの理由で、そうすることができない場合は、Option Strict を Off に設定し、変数を オブジェクト型 (Object) として宣言します。このようにすると、任意の型のオブジェクトを変数に代入できるようになります。変数に代入しているオブジェクトが受け入れ可能な型であることを確認する必要があります。この確認には、TypeOf 演算子 (Visual Basic) を使用できます。
他のコンポーネントが変数にアクセスできない
Visual Basic では、名前の大文字と小文字は区別されません。2 つの名前の違いが英字の大文字と小文字の違いだけの場合、コンパイラでは 2 つを同じ名前と解釈します。たとえば、ABC と abc は、宣言された同じ要素を参照していると見なされます。
しかし、共通言語ランタイム (CLR: Common Language Runtime) のバインディングでは大文字と小文字が区別されます。このため、アセンブリまたは DLL を作成し、他のアセンブリで使用できるようにする場合は、大文字と小文字が区別されるようになります。たとえば、ABC という名前の要素を持つクラスを定義し、他のアセンブリから共通言語ランタイムを通じてこのクラスを使用する場合は、この要素を ABC として参照する必要があります。後でクラスを再コンパイルして要素の名前を abc に変更すると、このクラスを使用していた他のアセンブリがこの要素にアクセスできなくなります。したがって、アセンブリを更新してリリースするときには、パブリックな要素の名前の大文字と小文字を変更しないようにする必要があります。
詳細については、「共通言語ランタイム」を参照してください。
修正方法
他のコンポーネントからアクセスできる変数にするには、大文字と小文字が区別されるものとして変数の名前を扱います。作成したクラスまたはモジュールをテストするときには、他のアセンブリが適切な変数にバインドされることを確認します。コンポーネントの公開後は、大文字と小文字の変更を含め、既存の変数名は一切変更しないようにします。
誤った変数が使用される
同じ名前の変数が複数あると、Visual Basic のコンパイラは、その名前への参照を解決しようとします。変数のスコープが異なる場合、コンパイラは、参照を最も狭いスコープの宣言に解決します。変数のスコープが同じ場合、解決は失敗し、コンパイラはエラーを発行します。詳細については、「同じ名前を持つ複数の変数がある場合に参照を解決する」を参照してください。
修正方法
同じ名前で定義が異なる変数を使わないようにします。他のアセンブリまたはプロジェクトを使用している場合、そのような外部コンポーネントで定義された名前を使うことはできるだけ避けてください。同じ名前の変数が複数ある場合、変数への参照に修飾子を付けるようにします。詳細については、「方法 : 同じ名前を持つ 2 つの要素を区別する」を参照してください。