ByRef vs ByVal澄清 [英] ByRef vs ByVal Clarification

查看:91
本文介绍了ByRef vs ByVal澄清的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始上一堂课,处理与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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆