C# 字节数组通过没有引用的方法受到影响

本文关键字:引用 方法 受到影响 字节 字节数 数组 | 更新日期: 2023-09-27 17:57:10

这是一个使用异步套接字接收数据的工作(无用)示例。完整的代码可以在 MSDN 上找到。

public class Class1
{
    private static void Receive( Socket client )
    {
        StateObject state = new StateObject();
        state.workSocket = client;
        //state.buffer is a empty byte array
        client.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReceiveCallback), state);
    }
    private static void ReceiveCallback( IAsyncResult ar )
    {
        StateObject state = (StateObject) ar.AsyncState;
        Socket client = state.workSocket;
        int bytesRead = client.EndReceive(ar);
        //state.buffer contains now all the received data.
        state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
    }
}
public class StateObject
{
    public Socket workSocket = null;
    public const int BufferSize = 256;
    public byte[] buffer = new byte[BufferSize];
    public StringBuilder sb = new StringBuilder();
}

BeginReceive方法中,应该不可能影响state.buffer字段,因为没有refout关键字。

但是字节数组实际上具有更改的值。

state.buffer字段怎么可能在Receive Methode中为空,然后在ReceiveCallback方法中访问时包含所有接收的数据?

C# 字节数组通过没有引用的方法受到影响

应该不可能影响 state.buffer 字段,因为没有 ref 或 out 关键字

不。这不是真的。state.buffer指向的实际对象可以通过其他方法更改,但不能更改其引用

下面是一个简单的示例:

static void Main()
{
    byte[] arr = new byte[] { 1, 2, 3, 4, 5 };
    ChangeTheObject(arr);
    foreach(byte b in arr) {
         Console.WriteLine(b);
    }
}
static void ChangeTheObject(byte[] arr)
{
     arr[2] = 7;
}

Main()将打印

1
2
7
4
5

对象本身可以通过接收它的方法进行更改。


但是,您无法更改引用本身。

static void ChangeTheReference(byte[] arr)
{
     arr = new byte[] { 6, 7, 8, 9, 10 };
}

这不会更改 Main() 中原始数组的内容,因为您已将本地引用重新分配给新对象。您没有更改原始对象。这就是ref关键字派上用场的地方。


示例中的方法更改的是数组的内容,而不是引用。

如果您至少

花时间阅读您发布的 MSDN 链接上的评论,您就会明白发生了什么:

开始从远程设备接收数据。

client.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, 
     new AsyncCallback(ReceiveCallback), state);

从远程设备读取数据。

int bytesRead = client.EndReceive(ar);

下次,在声称什么是可能的或不可能之前,花更多的时间阅读和理解已经解释的内容。