【问题标题】:C#: Why is Networkstream.Read() able to change the buffer variable without out/ref keywordC#:为什么 Networkstream.Read() 能够在没有 out/ref 关键字的情况下更改缓冲区变量
【发布时间】:2018-12-24 10:35:21
【问题描述】:

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

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]

但如果我在 testread() 中添加“out”关键字确实有效:

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[] 呢? 吓人..

【问题讨论】:

    标签: c# sockets network-programming ref out


    【解决方案1】:

    这证明你不能在没有“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"
    

    这会更新对象,但不需要更改 参数 即可。它改变了参数指向的对象

    【讨论】:

      【解决方案2】:

      很可能是因为它不执行buffer = data 分配。相反,它直接读入作为参数传递的缓冲区,即如果您在循环中执行buffer[i] = 1,则可以模拟它。

      【讨论】:

        猜你喜欢
        • 2010-09-28
        • 2021-08-31
        • 1970-01-01
        • 1970-01-01
        • 2023-04-05
        • 2014-01-11
        • 1970-01-01
        • 1970-01-01
        • 2012-03-22
        相关资源
        最近更新 更多