VB.net中的ByVal和ByRef到底有何区别?

时间:2021-04-03 13:55:18
ByVal和ByRef在字面上是传参和传值,可是在实际应用中,如对象,string默认是用
ByRef的方式,其它的基本变量用ByVal的方式这可以定义为程序的标准,如C#中没有
要在函数中显式定义Byval还是ByRef的方式,真不明白为什么在VB.net中会要这些东东?如果想要ByVal方式传对象,可以用克隆的方式.
还请大家指点迷经?应该如何用好这两个关键字

14 个解决方案

#1


'byval 和 byref 用法简单示例
Option Explicit

Private Sub Command1_Click()
    Dim a As Integer
    a = 50

    DoByVal (a)
    MsgBox a
    
    DoByRef (a)
    MsgBox a
End Sub
Private Sub DoByVal(ByVal intPara As Integer)
    intPara = intPara + 50
End Sub

Private Sub DoByRef(ByRef intPara As Integer)
    intPara = intPara + 50
End Sub

#2


ByVal 相当于c语言中一般的参数(比如  int a)
ByRef 相当于c语言中变量的的地址(比如 &a)

#3


以上说的我明白,多谢.只是从语言易用性来说,VB.net不如C#和JAVA简洁.
如ByVal和ByRe很可能会写错,给程序调试带来不便.而且,如果对对象用
ByVal传值时,如果改变对象的属性,也是可以的.这与ByVal的本意不是矛盾吗?
而定义规则后,如C#语言:  
  int DoByVal(int intPara){
     intPara = intPara + 50;
  }
  执行函数后intPara的值不会变化,相当于ByVal.如果要传参,可以用全局变量或返回函数解 决(这样可以减少程序发生错误的机会)

窃以为C#等从语法角度说是比VB.net更高效的语言,列位以为如何?  

#4


byval<in>
byref<out>
两者基本的差别

#5


你说的什么?是c++的模板?
byval,byref与参数输入输出有关吗?又不是存储过程!

#6


没有谁知道为什么VB.net中会增加这些无用的东西?VB.net用的都是以前VB转过来的人吧?

#7


区别很明显。
ByRef 能够更改变量和它指向的实例的成员。
ByVal 以更改它指向的实例的成员。

#8


完全正确

#9


就是传值和传引用。
要注意传递数组,他们两者之间微妙的差别。

#10


"没有谁知道为什么VB.net中会增加这些无用的东西?VB.net用的都是以前VB转过来的人吧?"

没用的东西!使原本就有的,和为没用.

#11


我只是对使用ByVal还可以改变对象比较难以理解?这对初学者不会起误导作用吗?

#12


不讲废话, 看代码。
Public Class A
    Private _size As Int32
    
    Public Property size()
        Get
            Return _size
        End Get
        Set(ByVal Value)
            _size = Value
        End Set
    End Property

End Class

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim a1 As A
        Dim t As Int32
        a1 = New A
        a1.size = 8
        t = a1.size
        updateA1ByVal(a1)
        If Not IsNothing(a1) Then
            Console.WriteLine("a1 update by val from " & t & " to " & a1.size)
        Else
            Console.WriteLine("a1 changed to nothing by updateA1ByVal")
        End If
        updateA1ByRef(a1)
        If Not IsNothing(a1) Then
            Console.WriteLine("a1 update by ref from " & t & " to " & a1.size)
        Else
            Console.WriteLine("a1 changed to nothing by updateA1ByRef")
        End If
    End Sub

    Private Sub updateA1ByVal(ByVal a As A)
        a.size = 9
        a = Nothing
    End Sub

    Private Function updateA1ByRef(ByRef a As A)
        a.size = 9
        a = Nothing
    End Function

执行结果
a1 update by val from 8 to 9
a1 changed to nothing by updateA1ByRef

    这个跟.net的后期绑定有关系,传递的参数实际上不是类A的一个对象,而是指向这个对象的一个值a1, 请注意a1本身不仅是一个符号,它有自己的值。
    byVal时,参数a的值和a1一样,所以都指向最初New出的那个实例(后期绑定)。当a.size先被修改为9时,因为最初New出的实例应经和它绑定,所以也被修改为9,然后参数a置为nothing,解除了绑定。
    byRef时,参数a和a1一样(别名),所以当a被置为nothing时,a1也被置为nothing。

套用一句大师的话
In C++: pass object by value , pass object by reference 。
In Java: pass object reference by value
也许我们可以这样说
In vb.net: pass object reference by value, pass object by reference。

!~~


#13


用ByRef传递参数,参数值会在子程序中改变。
用ByVal传递参数,参数值不会在子程序中改变。

#14


ByRef是按引用方式传递参数,只是传递参数的内存地址,子程序按照内存地址和数据类型从内存中读取数据。
ByVal是按值传递,主程序直接把参数传递给子程序。
这两种方式和C中,按指针方式和按值传递参数一样

#1


'byval 和 byref 用法简单示例
Option Explicit

Private Sub Command1_Click()
    Dim a As Integer
    a = 50

    DoByVal (a)
    MsgBox a
    
    DoByRef (a)
    MsgBox a
End Sub
Private Sub DoByVal(ByVal intPara As Integer)
    intPara = intPara + 50
End Sub

Private Sub DoByRef(ByRef intPara As Integer)
    intPara = intPara + 50
End Sub

#2


ByVal 相当于c语言中一般的参数(比如  int a)
ByRef 相当于c语言中变量的的地址(比如 &a)

#3


以上说的我明白,多谢.只是从语言易用性来说,VB.net不如C#和JAVA简洁.
如ByVal和ByRe很可能会写错,给程序调试带来不便.而且,如果对对象用
ByVal传值时,如果改变对象的属性,也是可以的.这与ByVal的本意不是矛盾吗?
而定义规则后,如C#语言:  
  int DoByVal(int intPara){
     intPara = intPara + 50;
  }
  执行函数后intPara的值不会变化,相当于ByVal.如果要传参,可以用全局变量或返回函数解 决(这样可以减少程序发生错误的机会)

窃以为C#等从语法角度说是比VB.net更高效的语言,列位以为如何?  

#4


byval<in>
byref<out>
两者基本的差别

#5


你说的什么?是c++的模板?
byval,byref与参数输入输出有关吗?又不是存储过程!

#6


没有谁知道为什么VB.net中会增加这些无用的东西?VB.net用的都是以前VB转过来的人吧?

#7


区别很明显。
ByRef 能够更改变量和它指向的实例的成员。
ByVal 以更改它指向的实例的成员。

#8


完全正确

#9


就是传值和传引用。
要注意传递数组,他们两者之间微妙的差别。

#10


"没有谁知道为什么VB.net中会增加这些无用的东西?VB.net用的都是以前VB转过来的人吧?"

没用的东西!使原本就有的,和为没用.

#11


我只是对使用ByVal还可以改变对象比较难以理解?这对初学者不会起误导作用吗?

#12


不讲废话, 看代码。
Public Class A
    Private _size As Int32
    
    Public Property size()
        Get
            Return _size
        End Get
        Set(ByVal Value)
            _size = Value
        End Set
    End Property

End Class

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim a1 As A
        Dim t As Int32
        a1 = New A
        a1.size = 8
        t = a1.size
        updateA1ByVal(a1)
        If Not IsNothing(a1) Then
            Console.WriteLine("a1 update by val from " & t & " to " & a1.size)
        Else
            Console.WriteLine("a1 changed to nothing by updateA1ByVal")
        End If
        updateA1ByRef(a1)
        If Not IsNothing(a1) Then
            Console.WriteLine("a1 update by ref from " & t & " to " & a1.size)
        Else
            Console.WriteLine("a1 changed to nothing by updateA1ByRef")
        End If
    End Sub

    Private Sub updateA1ByVal(ByVal a As A)
        a.size = 9
        a = Nothing
    End Sub

    Private Function updateA1ByRef(ByRef a As A)
        a.size = 9
        a = Nothing
    End Function

执行结果
a1 update by val from 8 to 9
a1 changed to nothing by updateA1ByRef

    这个跟.net的后期绑定有关系,传递的参数实际上不是类A的一个对象,而是指向这个对象的一个值a1, 请注意a1本身不仅是一个符号,它有自己的值。
    byVal时,参数a的值和a1一样,所以都指向最初New出的那个实例(后期绑定)。当a.size先被修改为9时,因为最初New出的实例应经和它绑定,所以也被修改为9,然后参数a置为nothing,解除了绑定。
    byRef时,参数a和a1一样(别名),所以当a被置为nothing时,a1也被置为nothing。

套用一句大师的话
In C++: pass object by value , pass object by reference 。
In Java: pass object reference by value
也许我们可以这样说
In vb.net: pass object reference by value, pass object by reference。

!~~


#13


用ByRef传递参数,参数值会在子程序中改变。
用ByVal传递参数,参数值不会在子程序中改变。

#14


ByRef是按引用方式传递参数,只是传递参数的内存地址,子程序按照内存地址和数据类型从内存中读取数据。
ByVal是按值传递,主程序直接把参数传递给子程序。
这两种方式和C中,按指针方式和按值传递参数一样