我刚从一个类开始处理到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.我的理解是,内存中的实例被复制,并且这个新实例被传递给值,我的代码设置_Socket来引用内存中的这个实例.是?
如果这是真的,那么我看不出为什么我想要使用属性,除了本机类型.我想象如果复制具有很多成员的类实例,可能会有相当的性能.另外,对于这个代码,我想象一个复制的套接字实例不会真的有效,但是我还没有测试过.
无论如何,如果你可以确认我的理解,或解释我的雾气逻辑中的缺陷,我会非常感激.
我认为你混淆了引用与值类型以及ByVal与ByRef的概念.即使他们的名字有点误导,他们是正交问题.
VB中的ByVal意味着提供的值的副本将被发送到该函数.对于值类型(整数,单等等),这将提供一个浅的副本.对于较大的类型,这可能是无效的.对于引用类型(String,类实例),引用的副本将被传递.因为复制通过变量传递给参数via =对调用函数不可见.
ByRef在VB.Net中意味着对原始值的引用将被发送到函数(1).几乎就像原来的价值在功能中直接使用.像=这样的操作将影响原始值,并在调用函数中立即显示.
Socket是一个引用类型(read class),因此通过ByVal传递它是便宜的.即使它执行副本,它是引用的副本,而不是实例的副本.
(1)这不是100%真的,因为VB.Net实际上支持在调用现场的几种ByRef.有关更多详细信息,请参阅以下博客条目
> http://blogs.msdn.com/b/jaredpar/archive/2010/01/21/the-many-cases-of-byref.aspx