Gibt es ein VB.NET-Äquivalent zu C # out-Parametern?

95

Hat VB.NET ein direktes Äquivalent zu C # out-Funktionsparametern, bei denen die an eine Funktion übergebene Variable nicht initialisiert werden muss?

cspolton
quelle

Antworten:

98

Nein, es gibt kein Äquivalent zum outSchlüsselwort in VB.

VB initialisiert jedoch automatisch alle lokalen Variablen in einer Methode, sodass Sie sie verwenden können, ByRefohne die Variable zuerst explizit initialisieren zu müssen.

Beispiel:

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

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

(Wenn Sie Code im Framework untersuchen (z. B. Double.TryParse ), werden möglicherweise die <OutAttribute>hinzugefügten Parameter angezeigt. Dies macht jedoch nur dann einen Unterschied, wenn der Aufruf für COM-Interop oder Plattformaufruf bereitgestellt wird.)

Guffa
quelle
2
@Spolto: Wenn Sie VBScript in VB übersetzen, sollten Sie sicherstellen, dass der explizite und der strikte Modus aktiviert sind. Es werden mehr Fehlermeldungen angezeigt, aber die meisten verweisen eher auf die Ursache von Problemen (z. B. Variable ohne Typ deklariert) als auf sekundäre Probleme (z. B. Variable ohne Typ deklariert Object, daher kann sie nicht für einen ByRef x As IntegerParameter verwendet werden).
Guffa
4
@Guffa: Ich weiß nicht, ob es sich um eine Versionssache handelt, aber ich erhalte auch Compiler-Warnungen, wenn nicht initialisierte Referenztypvariablen als ByRefParameter übergeben werden. (Es passiert nicht mit Werttyp-Parametern.)
Dan Tao
4
@ Dan Tao, Spolto: Das scheint der Unterschied zu sein, ich bekomme auch eine Warnung mit Referenztypen. Die Unfähigkeit, Parameter anzugeben, ist eine Einschränkung in der Sprache, und Sie müssen nur die Variablen initialisieren, um die Warnungen zu entfernen. Selbst Nothingwenn Sie ihnen zuweisen , wird die Warnung entfernt, obwohl das Ergebnis dadurch nicht geändert wird.
Guffa
1
@ Guffa: Ja, ich habe Nothingsie bisher zugewiesen . Es ist nur zeitaufwändig, da ich es hunderte Male auf einer großen Legacy-Website tun muss. Vielen Dank für die Untersuchung.
Cspolton
3
@ MarkHurd: Dann ist die Abwertung ungerecht, weil ich bereits behandelt habe, dass das OutAttribut nicht dem C # -Schlüsselwort entspricht out.
Guffa
32

Nein, es gibt kein Äquivalent Konstrukt , das ein nicht-initialisierte Variable ermöglicht , ohne eine Warnung an eine Methode übergeben werden, aber, wie es in meiner erwähnten Frage und Antwort ein Angabe <Out()>Attribut auf einer ByRefParameterdefinition, obwohl VB ignoriert, wird behandelt von C # als outParameter.

Daher würde ich Referenzvariablen vorinitialisieren Nothing und angeben <Out()> ByRef, um die Absicht zu kennzeichnen (dies funktioniert, wenn C # -Benutzer jemals auf Ihre Methoden zugreifen).

Wenn Sie das Gefühl haben, zu wissen, wann Sie Nothingin ansonsten nicht zugewiesenen Referenzvariablen auf die Standardeinstellungen zugreifen möchten , können Sie auf Projektebene (Projekteigenschaften> Kompilieren) die Option "Warnkonfiguration" "Verwendung von Variablen vor der Zuweisung" auf "Keine" setzen Sie möchten die Konfiguration auf "Alle Konfigurationen" setzen, bevor Sie diese Einstellung ändern. Sie können sie auch in VS2015 (VB.NET 14) verwenden #Disable Warning BC42030.

Mark Hurd
quelle
3
Dies ist von Bedeutung. Ich hatte eine VB-Unterklasse von MembershipProvider und dann eine C # -Unterklasse der VB-Unterklasse. Der C # -Code erkannte nicht die Tatsache, dass die abstrakten Methoden im MembershipProvider bereits implementiert waren, bis ich das Attribut in der VB-Klasse für Parameter anwendete, die in der MembershipProvider-Basisklasse als out angegeben wurden.
Richard Collette
@RichardCollette Das ist wahrscheinlich eine Antwort auf meine verknüpfte Frage wert!
Mark Hurd
9

C # -Version

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

Vb.net Version

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

Hier finden Sie die Antwort

Aktualisieren

Wie im Kommentar angegeben, vergessen Sie nicht, Ihren Parameter zu initialisieren, der im Out-Slot verwendet wird

David
quelle
Im Allgemeinen stimme ich zu, dass ByRef dem Out am nächsten kommt . Allerdings ByRef wirft noch eine Warnung , wenn Sie eine Variable nicht initialisiert übergeben, wie die Frage stellt.
Richard
Meine Ablehnung war vor einiger Zeit: Die Website, auf die Sie verlinkt haben, ist sehr allgemein; Es werden keine spezifischen Probleme, Unterschiede und technischen Details aufgeführt. Auch Ihre Antwort beantwortet die Frage immer noch nicht.
Mark Hurd
1

Ich hatte das Problem in VB.NET, dass ich eine Funktion "by ref" aufgerufen habe, die ein Array zurückgegeben hat.

Obwohl der Compiler es als Warnung markiert hat, war es in Ordnung. Das Update ist super einfach und wahrscheinlich eine gute Programmierpraxis.

ich habe mich verändert

Dim m_arr_values() as Integer

fnRetArray(m_arr_values)

zu

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

fnRetArray(m_arr_values)

Es hilft auch beim Codieren, wenn Variablennamen beschreibend sind ...

Sub fnCreatePalette(ByRef arr_in_pal() As color, ByRef arr_out_pal() as uinteger)
    ...
End Sub
TheWhitde
quelle
3
Die ungarische Notation verstößt gegen die .NET Framework-Designrichtlinie.
Gqqnbig
0

Sie können die Referenzübergabemethode in VB.NET verwenden.

Sie benötigen den Out-Parametermechanismus in C #, da Sie damit keine Variable verwenden können, ohne sie zu initialisieren.

VB.NET benötigt kein spezielles Schlüsselwort, da es dies automatisch selbst tut.

Verwenden Sie einfach ByRef.

Josh
quelle
3
Dies beantwortet die Frage nicht und ist in Bezug auf C # falsch.
Cspolton
Mit dem byref können Sie nicht initialisieren und den params-Wert ändern. Im Gegensatz zum Parameter C # out können Sie den Parameter jedoch mit einem Wert initialisieren und in der Funktion verwenden, während Sie in C # durch das Schlüsselwort out gezwungen sind, diesen NUR als out-Parameter und NICHT als Eingabe für zu verwenden die Funktion. Wenn Sie diesen Parameter in Ihrer Funktion nicht ändern oder auf diesen Wert setzen, erkennt der Compiler dies nicht als Fehler, im Gegensatz zu C #, bei dem ein Kompilierungsfehler ausgegeben wird.
Pashute
0

VB hat das Attribut, das mit C # out identisch sein sollte, aber heute erhalten Sie immer noch eine Warnung, selbst wenn Sie es verwenden. Es gibt Details zum Reparieren im vblang-Bereich von Github. https://github.com/dotnet/vblang/issues/67 .

Paul Cohen
quelle
-5

Verwenden Sie das Schlüsselwort ByRef vor der Variablen.

deostroll
quelle
4
ByRefentspricht refParametern in C #, die initialisiert werden müssen, bevor sie an eine Funktion übergeben werden.
Cspolton