Czy istnieje odpowiednik VB.NET parametrów C # out?


Odpowiedzi:


98

Nie, outw języku VB nie ma odpowiednika słowa kluczowego.

Jednak VB automatycznie inicjalizuje wszystkie zmienne lokalne w metodzie, więc możesz ich użyć ByRefbez konieczności jawnej inicjalizacji zmiennej.

Przykład:

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

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

(Jeśli zbadasz kod w ramach (na przykład Double.TryParse ), możesz zobaczyć <OutAttribute>dodane do parametrów, ale ma to znaczenie tylko wtedy, gdy wywołanie jest zorganizowane dla międzyoperacyjności COM lub wywołania platformy.)


2
@Spolto: Jeśli tłumaczysz VBScript na VB, upewnij się, że włączono tryb Explicit i Strict. Dostaniesz więcej komunikatów o błędach, ale większość wskaże źródło problemów (np. Zmienna zadeklarowana bez typu), a nie problemy drugorzędne (np. Zmienna zadeklarowana bez typu staje się Object, więc nie można jej użyć jako ByRef x As Integerparametru).
Guffa,

4
@Guffa: Nie wiem, czy to kwestia wersji, ale ja również otrzymuję ostrzeżenia kompilatora podczas przekazywania niezainicjowanych zmiennych typu referencyjnego jako ByRefparametrów. (Nie dzieje się tak z parametrami typu wartości.)
Dan Tao

4
@Dan Tao, Spolto: Wydaje się, że na tym polega różnica, dostaję również ostrzeżenie dotyczące typów referencyjnych. Brak możliwości określenia parametrów jest ograniczeniem w języku i wystarczy zainicjować zmienne, aby pozbyć się ostrzeżeń. Nawet przypisanie Nothingdo nich pozbędzie się ostrzeżenia, chociaż nie zmienia to wyniku.
Guffa,

1
@Guffa: Tak, Nothingdo tej pory przypisywałem im zadania . Jest to po prostu czasochłonne, ponieważ muszę to robić setki razy w dużej, starszej witrynie internetowej. Dziękuję za zbadanie.
cspolton

3
@MarkHurd: Wtedy głos przeciwny jest niesprawiedliwy, ponieważ już omówiłem, że Outatrybut nie jest równoważny ze outsłowem kluczowym C # .
Guffa

32

Nie, nie ma równoważnej konstrukcji, która umożliwia przekazanie niezainicjowanej zmiennej do metody bez ostrzeżenia, ale, jak wspomniano w moim pytaniu i odpowiedzi, określając <Out()>atrybut w ByRefdefinicji parametru, chociaż VB go ignoruje, jest traktowany przez C # jako outparametr.

Tak więc wstępnie zainicjowałbym zmienne referencyjne Nothing i określiłem je, <Out()> ByRefaby zaznaczyć zamiar (to zadziała, jeśli użytkownicy C # kiedykolwiek uzyskają dostęp do twoich metod).

Jeśli czujesz, że wiesz, kiedy zamierzasz uzyskać dostęp do wartości domyślnych Nothingw innych nieprzypisanych zmiennych referencyjnych, możesz ustawić opcję „Konfiguracja ostrzeżenia” „Użycie zmiennej przed przypisaniem” na „Brak” na poziomie projektu (Właściwości projektu> Kompiluj i prawdopodobnie chcesz ustawić konfigurację na „Wszystkie konfiguracje” przed zmianą tego ustawienia) lub w VS2015 (VB.NET 14) możesz użyć #Disable Warning BC42030.


3
To jest znaczące. Miałem podklasę VB MembershipProvider, a następnie podklasę C # podklasy VB. Kod C # nie rozpoznawał faktu, że abstrakcyjne metody w MembershipProvider zostały już zaimplementowane, dopóki nie zastosowałem atrybutu w klasie VB dla parametrów, które zostały określone jako out w klasie bazowej MembershipProvider.
Richard Collette

@RichardCollette To chyba warto być odpowiedzią na moje powiązane pytanie!
Mark Hurd,

9

Wersja C #

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

Wersja Vb.net

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

Znalazłem odpowiedź tutaj

Aktualizacja

Jak stwierdzono w komentarzu, nie zapomnij zainicjować parametru, który będzie używany w gnieździe wyjściowym


Ogólnie rzecz biorąc, zgadzam się, że ByRef jest najbliższa rzecz do wyjazdu . Jednak ByRef nadal będzie generować ostrzeżenie, jeśli przekażesz zmienną niezainicjowaną, zgodnie z pytaniem.
Richard

Mój głos przeciwny pochodzi z całkiem dawna: Witryna, do której odsyłasz, jest bardzo ogólna; nie wymienia konkretnych problemów, różnic i szczegółów technicznych. Twoja odpowiedź nadal nie odpowiada na pytanie.
Mark Hurd,

1

Miałem problem w VB.NET, że nazwałem funkcję „by ref”, która przekazała tablicę z powrotem.

Mimo że kompilator oznaczył to jako ostrzeżenie, było w porządku. Poprawka jest super prosta i prawdopodobnie dobra praktyka programistyczna.

Zmieniłam

Dim m_arr_values() as Integer

fnRetArray(m_arr_values)

do

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

fnRetArray(m_arr_values)

Jest to również pomocne podczas kodowania, jeśli nazwy zmiennych są opisowe ...

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

3
Notacja węgierska jest sprzeczna z wytycznymi dotyczącymi projektowania frameworka .NET.
Gqqnbig

0

Możesz użyć metody przekazywania przez odwołanie w VB.NET.

Potrzebujesz mechanizmu parametrów Out w C #, ponieważ nie pozwala on na użycie żadnej zmiennej bez jej zainicjowania.

VB.NET nie potrzebuje specjalnego słowa kluczowego, ponieważ robi to automatycznie.

Po prostu użyj ByRef.


3
To nie odpowiada na pytanie i jest błędne w odniesieniu do języka C #.
cspolton

Byref pozwala nie inicjalizować i pozwala na zmianę wartości params. Ale w przeciwieństwie do parametru C # out, POZWALA on zainicjować parametr wartością i użyć go w funkcji, podczas gdy w języku C # słowo kluczowe out wymusza używanie tego TYLKO jako parametru wyjściowego, a NIE jako danych wejściowych do funkcja. Ponadto, jeśli nie zmienisz ani nie ustawisz wartości tego parametru w funkcji, kompilator nie wykryje tego jako błędu, w przeciwieństwie do C #, w którym zostanie wystawiony błąd kompilacji.
pashute


-5

Użyj słowa kluczowego ByRef przed zmienną.


4
ByRefjest odpowiednikiem refparametrów w C #, które muszą zostać zainicjowane przed przekazaniem do funkcji.
cspolton,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.