ByRef vs ByVal澄清 [英] ByRef vs ByVal Clarification
问题描述
我刚刚开始上一堂课,处理与TCP服务器的客户端连接。这是我到目前为止编写的代码:
I'm just starting on a class to handle client connections to a TCP server. Here is the code I've written thus far:
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
,是吗?
So, on my overloaded constructor, I am accepting a reference to an instance of a System.Net.Sockets.Socket
, yes?
现在,在我的 Socket
属性,设置该值时,必须为 ByVal
。据我了解,内存中的 instance 已复制 ,并且此 new实例被传递给 value
,我的代码设置 _Socket
来引用内存中的该实例。是吗?
Now, on my Socket
property, when setting the value, it is required to be ByVal
. It is my understanding that the instance in memory is copied, and this new instance is passed to value
, and my code sets _Socket
to reference this instance in memory. Yes?
如果是这样,那么我看不到为什么要对本机类型使用任何属性。我想如果复制具有很多成员的类实例会给性能带来很大的影响。另外,对于这段代码,我想像一个复制的套接字实例将无法真正工作,但是我尚未对其进行测试。
If this is true, then I can't see why I would want to use properties for anything but native types. I'd imagine there can be quite a performance hit if copying class instances with lots of members. Also, for this code in particular, I'd imagine a copied socket instance wouldn't really work, but I haven't tested it yet.
无论如何,如果您可以肯定我的理解,或者解释我的模糊逻辑中的缺陷,我将不胜感激。
Anyway, if you could either confirm my understanding, or explain the flaws in my foggy logic, I would greatly appreciate it.
推荐答案
我认为您是重新混淆了引用与值类型以及 ByVal
与 ByRef
的概念。即使它们的名称有点误导,但它们是正交的问题。
I think you're confusing the concept of references vs. value types and ByVal
vs. ByRef
. Even though their names are a bit misleading, they are orthogonal issues.
ByVal
在VB.NET中意味着提供的值的副本将发送到函数。对于值类型(整数
,单
等),这将提供值的浅表副本。对于较大的类型,这可能效率很低。但是,对于引用类型( String
,类实例),将传递引用的副本。因为副本通过 =
传递给参数突变,所以调用函数将看不到该副本。
ByVal
in VB.NET means that a copy of the provided value will be sent to the function. For value types (Integer
, Single
, etc.) this will provide a shallow copy of the value. With larger types this can be inefficient. For reference types though (String
, class instances) a copy of the reference is passed. Because a copy is passed in mutations to the parameter via =
it won't be visible to the calling function.
ByRef
意味着对原始值的引用将发送到函数(1)。就像原始值直接在函数中使用一样。像 =
这样的操作会影响原始值,并在调用函数中立即可见。
ByRef
in VB.NET means that a reference to the original value will be sent to the function (1). It's almost like the original value is being directly used within the function. Operations like =
will affect the original value and be immediately visible in the calling function.
Socket
是引用类型(读取类),因此将它与 ByVal
传递是便宜的。即使它确实执行了副本,也只是引用的副本,而不是实例的副本。
Socket
is a reference type (read class) and hence passing it with ByVal
is cheap. Even though it does perform a copy it's a copy of the reference, not a copy of the instance.
(1)这不是100%正确,因为VB.NET实际上在呼叫站点上支持多种ByRef。有关更多详细信息,请参见博客条目 ByRef的许多情况
(1) This is not 100% true though because VB.NET actually supports several kinds of ByRef at the callsite. For more details, see the blog entry The many cases of ByRef
这篇关于ByRef vs ByVal澄清的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!