¿Existe un equivalente VB.NET de los parámetros de salida de C #?

95

¿VB.NET tiene un equivalente directo a los outparámetros de la función C # , donde la variable pasada a una función no necesita ser inicializada?

cspolton
fuente

Respuestas:

98

No, no existe un equivalente de la outpalabra clave en VB.

Sin embargo, VB inicializa automáticamente todas las variables locales en un método, por lo que puede usarlo ByRefsin necesidad de inicializar explícitamente la variable primero.

Ejemplo:

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

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

(Si examina el código en el marco (por ejemplo, Double.TryParse ), puede ver los <OutAttribute>parámetros agregados, pero eso solo hace una diferencia cuando la llamada se calcula para la interoperabilidad COM o la invocación de la plataforma).

Guffa
fuente
2
@Spolto: si está traduciendo VBScript a VB, debe asegurarse de activar el modo explícito y estricto. Obtendrá más mensajes de error, pero la mayoría apuntará a la fuente de los problemas (por ejemplo, variable declarada sin tipo) en lugar de problemas secundarios (por ejemplo, la variable declarada sin tipo se convierte Object, por lo que no se puede usar para un ByRef x As Integerparámetro).
Guffa
4
@Guffa: No sé si se trata de una versión, pero yo también recibo advertencias del compilador cuando paso variables de tipo de referencia no inicializadas como ByRefparámetros. (No sucede con los parámetros de tipo de valor.)
Dan Tao
4
@Dan Tao, Spolto: Esa parece ser la diferencia, también recibo una advertencia con los tipos de referencia. La imposibilidad de especificar los parámetros es una limitación en el idioma, y ​​solo tiene que inicializar las variables para deshacerse de las advertencias. Incluso asignarlos Nothingeliminará la advertencia aunque no cambie el resultado.
Guffa
1
@Guffa: Sí, les he estado asignando Nothinghasta ahora. Simplemente lleva mucho tiempo, ya que tengo que hacerlo cientos de veces en un gran sitio web heredado. Gracias por investigar.
cspolton
3
@MarkHurd: Entonces el voto negativo es injusto, porque ya he dicho que el Outatributo no es equivalente a la outpalabra clave C # .
Guffa
32

No, no existe una construcción equivalente que permita pasar una variable no inicializada a un método sin una advertencia, pero, como mencioné en mi pregunta y respuesta, especificar un <Out()>atributo en unByRef definición de parámetro, aunque VB lo ignora, es tratado por C # como outparámetro.

Entonces, preinicializaría las variables de referencia para Nothing y las especificaría <Out()> ByRefpara indicar la intención (eso funcionará si los usuarios de C # alguna vez acceden a sus métodos).

Si cree que sabe cuándo tiene la intención de acceder al valor predeterminado Nothingen las variables de referencia no asignadas, puede establecer la "Configuración de advertencia" "Uso de la variable antes de la asignación" en "Ninguno" en el nivel del proyecto (Propiedades del proyecto> Compilar, y probablemente desea establecer Configuración en "Todas las configuraciones" antes de cambiar esta configuración), o, en VS2015 (VB.NET 14), puede usar #Disable Warning BC42030.

Mark Hurd
fuente
3
Esto es significativo. Tenía una subclase VB de MembershipProvider y luego una subclase C # de la subclase VB. El código C # no reconocía el hecho de que los métodos abstractos en MembershipProvider ya se habían implementado hasta que apliqué el atributo en la clase VB para los parámetros que se especificaron como en la clase base MembershipProvider.
Richard Collette
@RichardCollette ¡Probablemente valga la pena ser una respuesta a mi pregunta vinculada!
Mark Hurd
9

Versión C #

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

Versión 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

Encontré la respuesta aquí

Actualizar

Como se indica en el comentario, no olvide inicializar su parámetro que se usará en la ranura de salida

David
fuente
En general, estoy de acuerdo en que ByRef es lo más parecido al out . Sin embargo, ByRef seguirá emitiendo una advertencia si pasa una variable sin inicializar, como pide la pregunta.
Richard
Mi voto negativo fue de hace bastante tiempo: el sitio web al que ha vinculado es muy general; no enumera problemas, diferencias ni tecnicismos específicos. Además, su respuesta aún no responde a la pregunta.
Mark Hurd
1

Tuve el problema en VB.NET que llamé a una función "por ref" que devolvió una matriz.

Aunque el compilador lo marcó como una advertencia, estaba bien. La solución es súper simple y probablemente una buena práctica de programación.

Cambié

Dim m_arr_values() as Integer

fnRetArray(m_arr_values)

a

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

fnRetArray(m_arr_values)

También ayuda a la hora de codificar si los nombres de las variables son descriptivos ...

Sub fnCreatePalette(ByRef arr_in_pal() As color, ByRef arr_out_pal() as uinteger)
    ...
End Sub
TheWhitde
fuente
3
La notación húngara va en contra de las pautas de diseño de .NET Framework.
Gqqnbig
0

Puede utilizar el método de paso por referencia en VB.NET.

Necesita el mecanismo de parámetro Out en C #, porque no le permite usar ninguna variable sin inicializarla.

VB.NET no necesita una palabra clave especial, ya que lo hace automáticamente por sí mismo.

Solo usa ByRef.

Josh
fuente
3
Esto no responde a la pregunta y está mal con respecto a C #.
cspolton
El byref le permite no inicializar y le permite cambiar el valor de los parámetros. Pero, a diferencia del parámetro de salida de C #, SÍ PERMITE inicializar el parámetro con un valor y usarlo en la función, mientras que en C # la palabra clave de salida lo obliga a usar esto SÓLO como un parámetro de salida y NO como entrada para la función. Además, si no cambia o establece un valor para este parámetro dentro de su función, el compilador no lo detectará como un error, a diferencia de C #, donde se emitirá un error de compilación.
pashute
0

VB tiene el atributo que debería ser el mismo que C # out, pero hoy todavía recibe una advertencia incluso si lo usa. Hay detalles sobre cómo solucionarlo en el área vblang de github. https://github.com/dotnet/vblang/issues/67 .

Paul Cohen
fuente
-5

Utilice la palabra clave ByRef antes de la variable.

deostroll
fuente
4
ByRefes equivalente a los refparámetros en C #, que deben inicializarse antes de pasar a una función.
cspolton