C#: Почему Networkstream.Read() может изменить буферную переменную без ключевого слова out/ref
Почему 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 записывает в byte[] без ключевого слова "out"/"ref"? Страшно..
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"
Это обновляет объект, но для этого не нужно изменять параметр. Изменяет объект, на который указывает параметр.
Скорее всего, потому что это не делает buffer = data
назначение. Вместо этого он читает непосредственно в буфер, переданный в качестве аргумента, т.е. если вы делаете buffer[i] = 1
в вашем цикле вы имитируете это.