C#:为什么Networkstream.Read()能够在没有out / ref关键字的情况下更改缓冲区变量

时间:2018-07-16 19:59:03

标签: c# sockets network-programming ref out

为什么NetworkStream.Read()可以写入字节[]?

byte[] data = new byte[16];

NetworkStream ns = new NetworkStream(socket);
ns.Read(data, 0, data.Length);

//data != new byte[16]

我认为您需要out / ref关键字才能写入变量。像这样:

ns.Read(out data, 0, data.Length);

如果我尝试重新创建该方法,它将不起作用:

public static void testread(byte[] buffer, int size)
{
    byte[] data = new byte[size];
    for (int i = 0; i < data.Length; i++)
    {
        data[i] = 1;
    }
    buffer = data;
}

byte[] data = new byte[16];
testread(data, data.Length);

//data == new byte[16]

但是如果我将“ out”关键字添加到testread()确实可以工作:

public static void testread(out byte[] buffer, int size)
{
    byte[] data = new byte[size];
    for (int i = 0; i < data.Length; i++)
    {
        data[i] = 1;
    }
    buffer = data;
}

byte[] data = new byte[16];
testread(data, data.Length);

//data != new byte[16]

这证明没有“ out” /“ ref”关键字就无法写入变量。但是NetworkStream如何在没有“ out” /“ ref”关键字的情况下写入byte []? 吓人。

2 个答案:

答案 0 :(得分:2)

  

这证明没有“ out” /“ ref”关键字就无法写入变量。

您需要在思想上将两个截然不同的概念分开:

  • 改变对象的状态
  • 重新分配变量的值(参数,局部变量,字段等)

(请注意,对于对象,后者意味着更改它所引用的对象)

out仅需Stream允许调用方传入一个对象(数组),并将其写入数组。不需要out。与以下内容没有什么不同

void SetCustomerName(Customer obj) { // for class Customer
    obj.Name = "Fred";
}
...
var x = new Customer();
SetCustomerName(x);
Console.WriteLine(x.Name); // prints "Fred"

这将更新对象,但无需更改参数即可。它将更改参数指向的对象

答案 1 :(得分:0)

最有可能是因为它没有执行buffer = data分配。相反,它直接读入作为参数传递的缓冲区,即,如果您在循环中执行buffer[i] = 1,则可以对其进行仿真。