Existe-t-il un équivalent VB.NET des paramètres C # out?

95

VB.NET a-t-il un équivalent direct aux outparamètres de fonction C # , où la variable passée dans une fonction n'a pas besoin d'être initialisée?

cspolton
la source

Réponses:

98

Non, il n'y a pas d'équivalent du outmot - clé dans VB.

Cependant, VB initialise automatiquement toutes les variables locales dans une méthode, vous pouvez donc utiliser ByRefsans avoir à initialiser explicitement la variable au préalable.

Exemple:

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

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

(Si vous examinez le code dans le framework (par exemple Double.TryParse ), vous pouvez voir les <OutAttribute>paramètres ajoutés à, mais cela ne fait une différence que lorsque l'appel est organisé pour l'interopérabilité COM ou l'appel de plate-forme.)

Guffa
la source
2
@Spolto: Si vous traduisez VBScript en VB, vous devez vous assurer d'activer le mode Explicite et Strict. Cela vous donnera plus de messages d'erreur, mais la plupart pointeront vers la source des problèmes (par exemple, une variable déclarée sans type) plutôt que des problèmes secondaires (par exemple, une variable déclarée sans type devient Object, donc elle ne peut pas être utilisée pour un ByRef x As Integerparamètre).
Guffa
4
@Guffa: Je ne sais pas si c'est un problème de version, mais je reçois aussi des avertissements du compilateur lorsque je passe des variables de type référence non initialisées en tant que ByRefparamètres. (Cela ne se produit pas avec les paramètres de type valeur.)
Dan Tao
4
@Dan Tao, Spolto: Cela semble être la différence, je reçois également un avertissement avec des types de référence. L'incapacité de spécifier les paramètres de sortie est une limitation dans le langage, et il vous suffit d'initialiser les variables pour supprimer les avertissements. Même leur attribuer Nothingéliminera l'avertissement même si cela ne change pas le résultat.
Guffa
1
@Guffa: Oui, je leur ai assigné Nothingjusqu'à présent. Cela prend juste du temps car je dois le faire des centaines de fois dans un grand site Web hérité. Merci d'avoir enquêté.
cspolton
3
@MarkHurd: Alors le vote défavorable est injuste, car j'ai déjà expliqué que l' Outattribut n'est pas équivalent au outmot-clé C # .
Guffa
32

Non, il n'y a pas de construction équivalente qui permet à une variable non initialisée d'être passée à une méthode sans avertissement, mais, comme mentionné dans ma question et réponse spécifiant un <Out()>attribut sur une ByRefdéfinition de paramètre, bien que VB l'ignore, est traité par C # comme outparamètre.

Donc, je pré-initialiserais les variables de référence Nothing et spécifierais<Out()> ByRef pour signifier l'intention (cela fonctionnera si les utilisateurs C # accèdent à vos méthodes).

Si vous pensez savoir quand vous avez l'intention d'accéder à la valeur Nothingpar défaut dans des variables de référence autrement non attribuées, vous pouvez définir la "Configuration d'avertissement" "Utilisation de la variable avant l'affectation" sur "Aucune" au niveau du projet (Propriétés du projet> Compiler, et vous souhaitez définir Configuration sur «Toutes les configurations» avant de modifier ce paramètre) ou, dans VS2015 (VB.NET 14), vous pouvez utiliser #Disable Warning BC42030.

Mark Hurd
la source
3
C'est significatif. J'avais une sous-classe VB de MembershipProvider, puis une sous-classe C # de la sous-classe VB. Le code C # ne reconnaissait pas le fait que les méthodes abstraites dans MembershipProvider avaient déjà été implémentées jusqu'à ce que j'applique l'attribut dans la classe VB pour les paramètres spécifiés comme dans la classe de base MembershipProvider.
Richard Collette
@RichardCollette Cela vaut probablement la peine d'être une réponse à ma question liée!
Mark Hurd
9

Version C #

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

Version de Vb.net

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

J'ai trouvé la réponse ici

Mettre à jour

Comme indiqué dans le commentaire, n'oubliez pas d'initialiser votre paramètre qui sera utilisé dans le slot de sortie

David
la source
En général, je conviens que ByRef est la chose la plus proche de la sortie . Cependant, ByRef lancera toujours un avertissement si vous transmettez une variable non initialisée, comme le demande la question.
Richard
Mon vote défavorable remonte à un certain temps: le site Web auquel vous avez lié est très général; il n'énumère pas les problèmes spécifiques, les différences et les détails techniques. De plus, votre réponse ne répond toujours pas à la question.
Mark Hurd
1

J'ai eu le problème dans VB.NET que j'ai appelé une fonction "par ref" qui a renvoyé un tableau.

Même si le compilateur l'a signalé comme un avertissement, tout allait bien. Le correctif est super simple et probablement une bonne pratique de programmation.

j'ai changé

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)

Cela aide également lors du codage si les noms de variables sont descriptifs ...

Sub fnCreatePalette(ByRef arr_in_pal() As color, ByRef arr_out_pal() as uinteger)
    ...
End Sub
TheWhitde
la source
3
La notation hongroise est contraire aux directives de conception du framework .NET.
Gqqnbig
0

Vous pouvez utiliser la méthode de passage par référence dans VB.NET.

Vous avez besoin du mécanisme de paramètre Out en C #, car il ne vous permet pas d'utiliser une variable sans l'initialiser.

VB.NET n'a pas besoin d'un mot clé spécial car il le fait automatiquement par lui-même.

Utilisez simplement ByRef.

Josh
la source
3
Cela ne répond pas à la question, et c'est faux par rapport à C #.
cspolton
Le byref vous permet de ne pas initialiser, et vous permet de changer la valeur des paramètres. Mais, contrairement au paramètre C # out, il VOUS PERMET d'initialiser le paramètre avec une valeur et de l'utiliser dans la fonction, alors qu'en C # le mot clé out vous oblige à utiliser ce UNIQUEMENT comme un paramètre out et NON comme entrée pour la fonction. De plus, si vous ne modifiez pas ou ne définissez pas de valeur pour ce paramètre dans votre fonction, le compilateur ne détectera pas cela comme une erreur, contrairement à C # où une erreur de compilation sera émise.
pashute
0

VB a l'attribut qui devrait être le même que C # out mais aujourd'hui, vous recevez toujours un avertissement même si vous l'utilisez. Il y a des détails sur la façon de le réparer dans la zone vblang de github. https://github.com/dotnet/vblang/issues/67 .

Paul Cohen
la source
-5

Utilisez le mot clé ByRef avant la variable.

déostroll
la source
4
ByReféquivaut aux refparamètres en C #, qui doivent être initialisés avant d'être passés dans une fonction.
cspolton