gpt4 book ai didi

vb.net - ByRef vs ByVal澄清

转载 作者:行者123 更新时间:2023-12-03 06:49:27 27 4
gpt4 key购买 nike

我只是从一个类开始处理与TCP服务器的客户端连接。这是我到目前为止编写的代码:

Imports System.Net.Sockets
Imports System.Net

Public Class Client
Private _Socket As Socket

Public Property Socket As Socket
Get
Return _Socket
End Get
Set(ByVal value As Socket)
_Socket = value
End Set
End Property

Public Enum State
RequestHeader ''#Waiting for, or in the process of receiving, the request header
ResponseHeader ''#Sending the response header
Stream ''#Setup is complete, sending regular stream
End Enum

Public Sub New()

End Sub

Public Sub New(ByRef Socket As Socket)
Me._Socket = Socket

End Sub
End Class

因此,在重载的构造函数上,我接受对 System.Net.Sockets.Socket实例的引用,是吗?

现在,在我的 Socket属性上,设置值时,需要将其设置为 ByVal。我的理解是复制了内存中的实例,并将这个新实例传递给 value,并且我的代码将 _Socket设置为引用内存中的该实例。是?

如果这是真的,那么我看不到为什么除了原始类型之外,我想对其他任何属性都使用属性。我想如果复制具有很多成员的类实例会对性能造成很大的影响。另外,对于此代码,我想像一个复制的套接字实例将无法真正工作,但我尚未对其进行测试。

无论如何,如果您可以确认我的理解或解释我模糊的逻辑中的缺陷,我将不胜感激。

最佳答案

我认为您混淆了引用与值类型以及ByValByRef的概念。即使它们的名称有点误导,但它们是正交的问题。

VB.NET中的ByVal意味着将提供的值的副本发送到该函数。对于值类型(IntegerSingle等),这将提供值的浅拷贝。对于较大的类型,这可能效率不高。但是,对于引用类型(String,类实例),将传递引用的副本。由于副本是通过=传递给参数的突变形式,因此调用函数将看不到该副本。

VB.NET中的ByRef意味着对原始值的引用将发送到函数(1)。就像原始值直接在函数中使用一样。像=这样的操作将影响原始值,并在调用函数中立即可见。
Socket是引用类型(读取类),因此将其与ByVal一起传递很便宜。即使它确实执行了副本,也只是引用的副本,而不是实例的副本。

(1)这不是100%正确,因为VB.NET实际上在 call 站点上支持多种ByRef。有关更多详细信息,请参见博客条目The many cases of ByRef

关于vb.net - ByRef vs ByVal澄清,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4383167/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com