違いはなんですか?私はいつもByValを使用していますが、いつすべきか、いつすべきでないかについてはよくわかりません...
参照を渡す場合、メソッドの値を変更すると、呼び出しサイトの変数も変更されます。
値を渡すと、メソッドで別の変数が作成された場合と同じになるため、変更しても、元の変数(呼び出しサイト)の値は変更されません。
したがって、実際には、通常、変数を値として渡す必要があります。明示的に必要な場合にのみ、参照として渡します。
ByRef =あなたはあなたの友人にあなたのタームペーパー(オリジナル)を渡し、彼はそれをマークアップしてあなたに返すことができます。
ByVal =あなたは姫にタームペーパーのコピーを渡し、彼はあなたに彼の変更を返しますが、あなたはそれらをあなた自身で元に戻さなければなりません。
私がそれを作ることができるのと同じくらい簡単です。
Byrefを使用する理由:
ByRefは、渡すオブジェクトにPOINTERを渡します。同じメモリ空間にいる場合、これはオブジェクトではなく「Word」だけを渡すことを意味します。渡すメソッドは、元のオブジェクトに変更を加えることができ、元のオブジェクトにあるため、元のオブジェクトに戻す必要はまったくありません。大規模なデータパスを高速化するのに役立ちます。 ByRefを使用して、オブジェクトを返す必要がないため、FUNCTION(VB内)ではなくSUBの使用を許可することもできます。
Byrefを使用しない理由:
メソッドは元のメソッドにアクセスできるため、行われた変更は即座に永続的になります。メソッドが失敗した場合、oblectが破損する可能性があります。 ByValを使用すると、コピーが作成され、コピー全体がメソッドに渡されます。その後、メソッドは情報を処理し、コピーを再調整するか、情報を報告するか、何もしません。
私はこの質問がほとんど答えられたことを知っています、しかし私はただ以下を追加したかったです...
関数に渡すオブジェクトはByRef/ByValの対象となりますが、そのオブジェクトに他のオブジェクトへの参照が含まれている場合は、ByRef/ByValに関係なく、呼び出されたメソッドによってそれらを変更できます。説明が不十分です。理解を深めるために、以下のコードを参照してください。
Public Sub Test()
Dim testCase As List(Of String) = GetNewList()
ByRefChange1(testCase)
'testCase = Nothing
testCase = GetNewList()
ByValChange1(testCase)
'testCase is unchanged
testCase = GetNewList()
ByRefChange2(testCase)
'testCase contains the element "ByRef Change 2"
testCase = GetNewList()
ByValChange2(testCase)
'testCase contains the element "ByVal Change 2"
End Sub
Public Function GetNewList() As List(Of String)
Dim result As List(Of String) = New List(Of String)
result.Add("Value A")
result.Add("Value B")
result.Add("Value C")
Return result
End Function
Public Sub ByRefChange1(ByRef aList As List(Of String))
aList = Nothing
End Sub
Public Sub ByValChange1(ByVal aList As List(Of String))
aList = Nothing
End Sub
Public Sub ByRefChange2(ByRef aList As List(Of String))
aList.Add("ByRef Change 2")
End Sub
Public Sub ByValChange2(ByVal aList As List(Of String))
aList.Add("ByVal Change 2")
End Sub
編集:
また、この関数が呼び出されたかどうかを検討してください。
Public Sub ByValChange3(ByVal aList As List(Of String))
aList.Add("ByVal Change 3")
aList = New List(Of String)
aList.Add("ByVal Change 4")
End Sub
この場合、「ByVal Change 3」が呼び出し元リストに追加されますが、「aList = New List」を指定した時点で、新しい参照を新しいオブジェクトにポイントし、呼び出し元から切り離されます。リスト。常識といつかあなたを捕まえるかもしれないので、心に留めておくべき何か。
ByRefは、2番目の戻り値のようなものです。オブジェクト自体ではなく、オブジェクトへの参照を関数に渡します。関数のByRef
パラメータの値を変更すると、関数の終了後にそれらの変更が表示されます。それが十分に明確でなかった場合は、 これを読んでください および これ 。
ByRef、1つの値には2つのアドレスがあります
したがって、x = 80の場合(80は値、xはアドレスの場合、たとえば変数yも80になる可能性があるため、xとyから80にアクセスできます)
@Tomと@kellotiによる回答が役に立ちます。さらに説明するためのコード例を次に示します。
Private Function ValMessage(ByVal SomeMessage As String)
SomeMessage = "Val Val Val" ' <-- this variable modification doesn't persist after the function finishes execution
ValMessage = "Some Return Value"
End Function
Private Function RefMessage(ByRef SomeMessage As String)
SomeMessage = "Ref Ref Ref" ' <-- this variable modification persists even after the function finishes execution
RefMessage = "Some Return Value"
End Function
Private Sub DoStuff()
Dim OriginalMessage As String
Dim OtherMessage As String
Dim AnotherMessage As String
OriginalMessage = "Original"
MsgBox ("ORIGINAL: " & OriginalMessage) '--> "Original"
OtherMessage = ValMessage(OriginalMessage)
MsgBox ("ORIGINAL: " & OriginalMessage) '--> "Original"
AnotherMessage = RefMessage(OriginalMessage)
MsgBox ("ORIGINAL: " & OriginalMessage) '--> "Ref Ref Ref" <--- this is the difference when you pass a paramter by reference
End Sub
これがあなたの質問に答えることを願っています
Sub last_column_process()
Dim last_column As Integer
last_column = 234
MsgBox last_column
trying_byref x:=last_column
MsgBox last_column
trying_byval v:=last_column
MsgBox last_column
End Sub
Sub trying_byref(ByRef x)
x = 345
End Sub
Sub trying_byval(ByRef v)
v = 555
End Sub
最後のサンプルにタイプミスがあった可能性があると考えてください。最後のサブは「byref」ではなく「byval」である必要があります。 :)
また、trying_byvalにmsgboxステートメントを追加して、意味を理解できるようにしました。
Sub begin()
Dim last_column As Integer
last_column = 234
MsgBox "Begin:" & last_column
trying_byref x:=last_column
MsgBox "byref:" & last_column
trying_byval v:=last_column
MsgBox "byval:" & last_column
End Sub
Sub trying_byref(ByRef x)
x = 111
End Sub
Sub trying_byval(ByVal v) '<--not ByRef, that was in sub trying_byref.
v = 222
MsgBox "In Here:" & v
End Sub
簡単な言葉で違いを説明しようと思います。
引数を値で渡すと、パラメータのみが入力されます。これが最も安全な方法であるため、95%のケースでデフォルトで使用されます。
引数を参照で渡すと、入力パラメーターと出力パラメーターの両方になります。出力パラメーターは、めったに使用されない副作用を作成する関数内で変更できます。