ByVal修飾子は、手続きや関数にパラメータを値によって渡すことを示します。Visual Basicでは、ByValはデフォルトで使用され、手続き内でパラメータに加えられた変更が、呼び出し側で渡された元の変数に影響を与えないことを保証します。
従来のVBバージョンでは、任意のパラメータを値または参照によって渡すことができました。言語が進化し、複雑なデータ型(構造体、クラス)が登場するにつれて、ByValとByRefの間の意識的な選択の重要性が増しました。
パラメータの受け渡し方法の誤った選択はしばしばエラーを引き起こします。呼び出しコードの変数が意図せず変更される可能性がある一方で、逆に変更を期待しても発生しないことがあります。
ByValは、手続きが値のコピーで作業する必要がある場合に使用されます。これは、原始データ型、構造体、時には参照型さえも、参照を保持することが重要な場合に適用されます。
コード例:
Sub Increment(ByVal number As Integer) number += 1 End Sub Dim myValue As Integer = 10 Increment(myValue) Console.WriteLine(myValue) ' 10を返します、11ではありません
主な特徴:
ByVal修飾子でオブジェクト(例えば、クラスのインスタンス)を渡した場合、どのように動作しますか?
回答: オブジェクトの参照のコピーが渡され、オブジェクトそのものではありません。手続きからオブジェクトのフィールドを変更することは可能で、変更は外部からも見えます。しかし、参照そのものを新しいものに置き換えることはできず、呼び出し側のコードには影響しません。
コード例:
Class Counters Public Value As Integer End Class Sub ModifyCounter(ByVal c As Counters) c.Value = 999 ' プロパティを変更! c = New Counters() ' この変更は呼び出し側のコードには見えません End Sub Dim example As New Counters() ModifyCounter(example) Console.WriteLine(example.Value) ' 999を出力します
手続き内で構造体のフィールドを変更した場合、ByValで渡し時に構造体の値は変わりますか?
回答: いいえ、構造体のインスタンス全体がコピーされ、変更は外部に影響を与えません。手続き内の構造体の各レコード、例えば、Pointはそれぞれ独自のものです。
パラメータに対して明示的にByValを指定する必要がありますか?
回答: いいえ、ByValはデフォルトで使用され、明示的な指定は可読性向上とコーディングスタイルの遵守のためのみです。
開発者が配列をByValで関数に渡し、要素を変更できることを期待して新しい配列が呼び出し側に作成されると思いました(実際には参照型は参照で渡されます)。
長所:
短所:
関数によって変更されるべきでない配列インデックスを渡すためにByValを使用します。内部でインデックスの値を変更しても、元の変数は影響を受けません。
長所:
短所: