Модификации массивов передаются по ссылке - PullRequest
3 голосов
/ 19 ноября 2008

Я недавно натолкнулся на какой-нибудь сторонний код C #, который выполняет следующее:

public int RecvByteDataFromPrinter(ref byte[] byteData)
{
    byte[] recvdata = new byte[1024];

    ///...fills recvdata array...       

    byteData = recvdata;
    return SUCCESS;
}

Что на самом деле делает в этом случае строка "byteData = recvdata"?

Похоже, что цель состоит в том, чтобы byteData содержал содержимое массива recvdata. Однако у меня сложилось впечатление, что вам нужно будет выполнить операцию Array.Copy(...), чтобы это произошло.

Действительно ли это изменяет ссылку на byteData, чтобы она указывала на вновь выделенный массив? Если это так, гарантируется ли сохранение этого массива?

Ответы [ 4 ]

7 голосов
/ 19 ноября 2008

Да, из-за ссылки - она ​​изменяет переданную ссылку. Ошиваться? ты имеешь ввиду - не уничтожено? Да, это не будет GC'd из-за новой ссылки. Старый массив (переданный) может быть GC'd, хотя после этого назначения, если больше нет ссылок ...

Array.Copy будет на самом деле копировать элементы, тогда вам не нужно "ref", но это займет больше времени

2 голосов
/ 19 ноября 2008

Вы правильно догадались, назначение изменяет ссылку на массив byteData, чтобы указывать на вновь выделенный массив (из-за ключевого слова ref). Вызывающие функцию «увидят» содержимое массива recvData (что бы там ни было заполнено).

И да, массив остается неизменным до тех пор, пока на него остается одна ссылка (в данном случае, какой бы массив вы ни передавали этой функции).

1 голос
/ 19 ноября 2008

Этот код назначит ссылку на массив recvdata на ссылку на массив byteData. .NET будет отслеживать назначение под прикрытиями в своей логике сборки мусора, чтобы байтовый массив, который был первоначально назначен для recvdata, не уходил под вас, пока byteData находится в области видимости.

0 голосов
/ 19 ноября 2008

Ссылка byteData теперь будет указывать на массив recvdata, давая ему корень. Он будет «задерживаться» до тех пор, пока все его корни не исчезнут (т.е. вызываемый избавится от переданного объекта byteData), и он станет кандидатом в коллекцию. Переданный исходный объект массива является кандидатом на сбор, как только метод вернется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...