Должен ли ByRef использоваться в функции? - PullRequest
0 голосов
/ 03 декабря 2018

Я действительно запутался, когда следует использовать ByRef и ByVal.Мне сказали, что функция всегда должна возвращать значение, когда Sub не должен / может возвращать несколько значений.Тем не менее, я действительно застрял, когда я должен использовать ByRef и ByVal.

   Function Check(ByRef valid As Boolean, ByVal prize As Integer) As Boolean

    If prize < 1000000 Or prize > 4000000 Then valid = False

    Return valid

End Function

Например, выше, мне нужно, чтобы действительное значение было изменено функцией, но если бы я использовал ByVal, это неизмените его, поскольку ByVal не сохраняет изменения значения и не передает его обратно.Пожалуйста, помогите, tyvm.

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

«ByRef» делает одну вещь: он изменяет локальную переменную или свойство, которое передается в качестве аргумента.Если вы не хотите этого делать, и редко делаете, его не следует использовать.

В вашем примере может оказаться возможным придумать сценарий, в котором этот код имеет какой-то смысл, но это никогда не будет действительно ясно.Он одновременно изменяет значение переменной в вызывающем методе и возвращает возможно измененное значение.

Два варианта использования ByRef - это условная инициализация и множественный возврат.Вы код Сорта делает оба.Но это происходит так, что это необычно и не очень полезно.Обычно значение инициализации происходит изнутри метода, в этом случае инициализация должна произойти первой.

Ядром функции является проверка, чтобы увидеть, находится ли цена в определенном диапазоне, но потому что «действительный»может уже иметь значение false, даже если значение 'цена' находится за пределами недопустимого диапазона, оно все равно может возвращать значение false.

Dim valid As Boolean = true
...
valid=valid AndAlso Check(price)

Было бы то же самое и было бы намного легче понять.

0 голосов
/ 04 декабря 2018

Правильно сказать, что Function всегда возвращает значение (даже если это значение Nothing), а Sub - нет.В C # все методы являются функциями, а C #, эквивалентный VB Sub, является функцией с типом возврата void

Значением по умолчанию для параметров в VB является ByVal, и вы должны использовать его почтикаждый раз.Редко вам нужно использовать ByRef.Ниже приведены несколько хороших рекомендаций:

  1. Если ваш метод не производит вывод, тогда он должен быть Sub.
  2. Если ваш метод производит один вывод, тогда это должен быть Function, который возвращает этот вывод.
  3. Если ваш метод выдает несколько выходов, вам нужно решить, существует ли естественный "первичный" вывод, например, Integer.TryParse всегда производит вывод Boolean, а также производит Integer выводится тогда и только тогда, когда Boolean равен True, поэтому Boolean является естественным первичным выходом.
  4. Если есть естественный первичный вывод, тогда ваш метод должен быть Function, которыйвозвращает первичный вывод и использует ByRef параметры для остальных.
  5. Если нет естественного первичного вывода, например, метода, который выводит окружность и площадь круга, тогда ваш метод должен быть Subкоторый использует параметры ByRef для всех выходов.

Обратите внимание, что единственные обстоятельства, при которых вам нужно объявить параметр ByRef, следующие:

  1. TПараметр является ссылочным типом, и вы хотите назначить новый объект параметру в методе, и это изменение повлияет на исходную переменную, переданную в вызов метода.
  2. Параметр является типом значения, и вы хотитеназначить новое значение параметру в методе, и это изменение повлияет на исходную переменную, которую вы передали вызову метода.
  3. Параметр является типом значения, и вы хотите установить поле или свойство параметравнутри метода, и это изменение влияет на исходную переменную, переданную в вызов метода.

Нет другой причины объявлять параметр ByRef.Люди из VB6 часто думают, что им нужно объявить параметры ссылочного типа ByRef, чтобы избежать копирования больших объектов, но это не так.Переменная ссылочного типа уже содержит ссылку на объект, а не сам объект.Передача параметра по значению копирует переменную, поэтому, если переменная содержит ссылку, ее копирование копирует ссылку на объект, а не на объект.

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