Чи є еквівалент VB.NET параметрам C # out?


95

Чи має VB.NET прямий еквівалент outпараметри функції C # , де змінну, передану у функцію, не потрібно ініціалізувати?

Відповіді:


98

Ні, outв VB немає еквівалента ключового слова.

Однак VB автоматично ініціалізує всі локальні змінні у методі, тому ви можете використовувати ByRefбез необхідності спочатку явно ініціалізувати змінну.

Приклад:

Sub Main()
  Dim y As Integer
  Test(y)
End Sub

Sub Test(ByRef x As Integer)
  x = 42
End Sub

(Якщо ви вивчаєте код у рамках (наприклад, Double.TryParse ), ви можете побачити <OutAttribute>додані до параметрів, але це має значення лише тоді, коли виклик скасовано для інтеропу COM або виклику платформи.)


2
@Spolto: Якщо ви перекладаєте VBScript у VB, вам слід увімкнути режим "Явний і суворий". Це отримає більше повідомлень про помилки, але більшість вкаже на джерело проблем (наприклад, змінна оголошена без типу), а не вторинні проблеми (наприклад, змінна оголошена без типу стає Object, тому її не можна використовувати для ByRef x As Integerпараметра).
Гуффа

4
@Guffa: Я не знаю, чи це версія, але я також отримую попередження компілятора при передачі неініціалізованих змінних типу опорного типу в якості ByRefпараметрів. (Це не відбувається з параметрами типу значень.)
Дан Тао

4
@Dan Tao, Spolto: Це, мабуть, різниця, я також отримую попередження з посиланнями. Неможливість вказати параметри є обмеженням у мові, і вам потрібно просто ініціалізувати змінні, щоб позбутися попереджень. Навіть призначивши Nothingїх, ви позбудетесь попередження, хоча це не змінить результату.
Гуффа

1
@Guffa: Так, я до цього часу призначав Nothingїх. Це просто забирає багато часу, оскільки мені доводиться робити це сотні разів на великому старовинному веб-сайті. Дякую за розслідування.
cspolton

3
@MarkHurd: Тоді зворотне право є несправедливим, тому що я вже зауважив, що Outатрибут не еквівалентний outключовому слову C # .
Гуффа

32

Ні, не існує еквівалентна конструкція , яка дозволяє не инициализирован змінної бути переданий методу без попередження, але, як уже згадувалося в моєму питанні і відповіді вказавши <Out()>атрибут на ByRefвизначення параметрів, хоча VB ігнорує його, це лікується C # як outпараметр.

Отже, я б попередньо ініціалізував посилання на змінні Nothing та вказав <Out()> ByRefдля позначення наміру (це спрацює, якщо користувачі C # коли-небудь отримуватимуть доступ до ваших методів).

Якщо вам здається, що ви знаєте, коли ви маєте намір отримати доступ до типових параметрів Nothingу непризначених посилальних змінних, ви можете встановити "Конфігурація попередження" "Використання змінної перед призначенням" на "Ні" на рівні проекту (Властивості проекту> Скомпілювати, і ви, ймовірно, хочете встановити Конфігурацію на "Усі конфігурації" перед тим, як змінити це налаштування), або, у VS2015 (VB.NET 14), ви можете використовувати #Disable Warning BC42030.


3
Це суттєво. У мене був підклас VB від MembershipProvider, а потім підклас C # підкласу VB. Код C # не розпізнавав той факт, що абстрактні методи в MembershipProvider вже були реалізовані, поки я не застосував атрибут у класі VB для параметрів, визначених як базовий клас MembershipProvider.
Річард Коллетт

@RichardCollette Це, мабуть, варто відповісти на моє пов'язане питання!
Марк Херд

9

C # версія

  void TestFunc(int x, ref int y, out int z) {
  x++;  
  y++;
  z = 5;
}

Версія Vb.net

    Sub TestFunc(ByVal x As Integer, ByRef y As Integer, ByRef z As Integer)
  x += 1
  y += 1 
  z = 5 
End Sub

Знайшов відповідь тут

Оновлення

Як зазначено в коментарі, не забудьте заздалегідь встановити свій параметр, який буде використаний у слоті


Загалом, я згоден , що ByRef найближче до від'їзду . Однак ByRef все-таки видасть попередження, якщо ви передасте змінну неініціалізовану, як задається питанням.
Річард

Мій відгук був дуже давно: Веб-сайт, на який ви посилаєтесь, дуже загальний; в ньому не перераховано конкретні питання, відмінності та технічні особливості. Також ваша відповідь все ще не відповідає на запитання.
Марк Херд

1

У VB.NET у мене виникла проблема, що я викликав функцію "ref", яка передала масив назад.

Хоча компілятор позначив це попередженням, це було добре. Виправлення дуже просте і, мабуть, хороша практика програмування.

я змінив

Dim m_arr_values() as Integer

fnRetArray(m_arr_values)

до

' Even though 'Nothing' is the default value, setting it
' stops the compiler complaining.
Dim m_arr_values() as Integer = Nothing

fnRetArray(m_arr_values)

Це також допомагає при кодуванні, якщо назви змінних є описовими ...

Sub fnCreatePalette(ByRef arr_in_pal() As color, ByRef arr_out_pal() as uinteger)
    ...
End Sub

3
Угорська нотація суперечить керівництву щодо дизайну .NET Framework.
Gqqnbig

0

Ви можете використовувати пропуск методом довідки у VB.NET.

Вам потрібен механізм параметрів Out в C #, оскільки він не дозволяє використовувати будь-яку змінну без ініціалізації.

VB.NET не потребує спеціального ключового слова, оскільки він автоматично робить це сам.

Просто використовуйте ByRef.


3
Це не відповідає на питання, і це неправильно щодо C #.
cspolton

Byref дозволяє не ініціалізувати, а також дозволяє змінити параметри. Але, на відміну від параметра C # out, це ДОБАВЛЯЄТЬ ініціалізувати параметр зі значенням та використовувати його у функції, тоді як у C # ключове слово змушує вас використовувати ТІЛЬКИ як вихідний параметр, а НЕ як вхід до функція. Крім того, якщо ви не зміните і не встановите значення для цього парамуму в межах вашої функції, компілятор не сприйме це як помилку, на відміну від C #, де буде видана помилка компіляції.
пашуте

0

VB має атрибут, який повинен бути таким же, як і C # out, але сьогодні ви все одно отримуєте попередження, навіть якщо ви його використовуєте. Є подробиці про його фіксацію в vblang області github. https://github.com/dotnet/vblang/isissue/67 .


-5

Використовуйте ключове слово ByRef перед змінною.


4
ByRefеквівалентний refпараметрам в C #, які потрібно ініціалізувати перед переходом у функцію.
cspolton
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.