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

95

Czy VB.NET ma bezpośredni odpowiednik outparametrów funkcji C # , gdzie zmienna przekazana do funkcji nie wymaga inicjalizacji?

cspolton
źródło

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.)

Guffa
źródło
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.

Mark Hurd
źródło
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

David
źródło
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
TheWhitde
źródło
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.

Josh
źródło
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
0

VB ma atrybut, który powinien być taki sam jak C # out, ale dziś nadal otrzymujesz ostrzeżenie, nawet jeśli go używasz. Szczegółowe informacje na temat jego naprawiania znajdują się w obszarze vblang na githubie. https://github.com/dotnet/vblang/issues/67 .

Paul Cohen
źródło
-5

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

deostroll
źródło
4
ByRefjest odpowiednikiem refparametrów w C #, które muszą zostać zainicjowane przed przekazaniem do funkcji.
cspolton,