VB.NET, объект, возвращаемый ссылкой из функции
это должен быть довольно распространенный вопрос, но я нигде не нашел прямого ответа.
если я создаю экземпляр объекта внутри функции в VB.NET и верните его, возвращает ли он его по ссылке или по значению. IE-должен ли я беспокоиться о производительности, если я напишу что-то вроде этого:
Public Function ret_obj_func() As big_object
Dim ret_obj As New big_obj(<lots of stuff>)
Return ret_obj
End Function
Если я вызову эту функцию откуда - то еще, будет ли она создавать экземпляр объекта в ret_obj, а затем создавать глубокую копию для передачи копии вызывающему объекту или будет ли это просто передавать ссылку?
3 ответов
Он просто передает ссылку (предполагая big_obj
- Это класс). Я бы не использовал термин "по ссылке" здесь, так как это имеет тонко другое значение, когда дело доходит до передачи параметров, но предполагая big_obj
является классом-ссылочным типом-значением ret_obj
является ссылкой,и эта ссылка будет возвращена.
у меня нет статей об этом с точки зрения VB, но если вы счастливы посмотреть на C#, вы можете найти эти статьи полезно:
здесь есть две дихотомические проблемы с аналогичным словарем: значение против ссылки типы, и проходя мимо переменные по сравнению с ссылкой.
значение v. ссылочные типы
первая проблема-значение против ссылки типы. Типы значений передаются через копирование - обычно. Типы значений:
- дата
- Char
- U / Int(16/32/64)
- Decimal
- одиночный и двойной
- Boolean
- структуры
- метки
все, кроме перечисленных выше типов, являются ссылочными типами. Когда объект передается, на самом деле передается его адрес памяти, который часто рассматривается как int на 32-битных платформах и длинный на 64-битных платформах.
передача по значению В. По Ссылке
второй вопрос, передает переменная по стоимости по сравнению с ссылкой.
переменная-это слот в определенной позиции в памяти, который может содержать материал. Для типов значений он содержит фактическое значение. Для ссылочных типов он содержит адрес памяти объекта в куче (или ничего).
По Стоимости
когда вы передаете переменную по значению, что бы ни было в месте памяти этой переменной, это то, что получает скопированный. Для типов значений это означает, что копируется само значение. Для ссылочных типов копируется адрес памяти объекта, на который ссылается переменная.
По Ссылке
помните, что переменная-это просто слот в память для хранения вещей. Когда вы передаете переменную по ссылке, вы передаете адрес этого слота (в отличие от данных в этом слоте).
Если эта переменная является типом значения, этот слот содержит значение само по себе, поэтому передаваемая вещь является указателем на значение.
Если эта переменная является ссылочным типом, слот содержит указатель на местоположение объекта в памяти, поэтому передаваемая вещь является указателем на вашу переменную (как и с типами значений), которая сама содержит другой указатель (не как типы значений), который приводит к местоположению памяти, содержащему объект, на который ссылается переменная.
это позволяет функции изменять переменную в другой функция, как это:
Sub IPassByReference
Dim myVariable As Boolean = False
IReceiveByReference myVariable
Debug.Print(myVariable.ToString()) 'Always prints True
End Function
Sub IReceiveByReference(ByRef flag As Boolean)
flag = True 'the memory address of myVariable was passed.
End Function
давайте сравним с ситуацией, когда вы проходите по значению:
Sub IPassByValue
Dim myVariable As Boolean = False
IReceiveByValue myVariable
Debug.Print(myVariable.ToString()) 'Always prints False
End Function
Sub IReceiveByValue(ByVal flag As Boolean)
flag = True 'the value of myVariable was passed.
End Function
В приведенном выше примере Boolean является типом значения. Если бы это был объект, IReceiveByReference имел бы возможность указать myVariable на совершенно новый объект, потому что он получил адрес myVariable - не Адрес объекта, на который указывает myVariable. Напротив, IReceiveByValue было передано только содержимое myVariable, поэтому оно не может измениться myVariable, чтобы указать на новый объект. Однако он все равно может изменить объект, установив его поля и свойства и вызвав его методы.
Возврат По Ссылке?
хотя функции могут передавать переменные по ссылке, они не могут возвращать их таким образом. Когда функция возвращается, ее локальные переменные больше не существуют (или ожидают очистки, если они выделены кучей). Поэтому функции всегда возвращаются по значению; поскольку локальные переменные не имеют действительные адреса памяти больше, нет никаких ссылок на переменные для возврата.
складывая все это вместе, когда вы возвращаете объект из функции, единственное, что копируется, - это адрес объекта. При возврате типа значения из функции копируется само значение.
это означает, что ссылочные типы по существу являются типами значений, где значение является адресом памяти объекта в куче (или ничего).
VB.NET не имеет возможности вернуться по ссылке. Как и C#, если на то пошло, но это было предложил. То, что вы на самом деле получаете, - это просто ссылка на объект. Так точно определить это оно возвращает ссылку на объект. Это не вернуться на ссылку как то, что вы могли бы сравнить с ByRef
ключевое слово.