Existe um VB.NET equivalente aos parâmetros de saída do C #?

95

O VB.NET tem um equivalente direto aos outparâmetros de função C # , onde a variável passada para uma função não precisa ser inicializada?

cspolton
fonte

Respostas:

98

Não, não há equivalente da outpalavra - chave em VB.

No entanto, o VB inicializa automaticamente todas as variáveis ​​locais em um método, então você pode usar ByRefsem precisar inicializar explicitamente a variável primeiro.

Exemplo:

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

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

(Se você examinar o código na estrutura (por exemplo, Double.ExperimenteParse ), poderá ver os <OutAttribute>parâmetros adicionados, mas isso só faz diferença quando a chamada é encaminhada para interoperabilidade COM ou invocação de plataforma.)

Guffa
fonte
2
@Spolto: Se você estiver traduzindo VBScript para VB, certifique-se de ativar os modos Explicit e Strict. Irá obter mais mensagens de erro, mas a maioria apontará para a origem dos problemas (por exemplo, variável declarada sem tipo) em vez de problemas secundários (por exemplo, a variável declarada sem tipo torna-se Object, por isso não pode ser usada para um ByRef x As Integerparâmetro).
Guffa
4
@ Guffa: Não sei se é uma questão de versão, mas também recebo avisos do compilador ao passar variáveis ​​de tipo de referência não inicializadas como ByRefparâmetros. (Isso não acontece com parâmetros de tipo de valor.)
Dan Tao
4
@Dan Tao, Spolto: Essa parece ser a diferença, também recebo um aviso com tipos de referência. A incapacidade de especificar os parâmetros de saída é uma limitação da linguagem, e você só precisa inicializar as variáveis ​​para se livrar dos avisos. Mesmo atribuindo Nothinga eles, o aviso será eliminado, embora não altere o resultado.
Guffa
1
@ Guffa: Sim, tenho atribuído Nothinga eles até agora. É muito demorado porque estou tendo que fazer isso centenas de vezes em um grande site legado. Obrigado por investigar.
cspolton
3
@MarkHurd: Então o downvote é injusto, porque eu já falei que o Outatributo não é equivalente à outpalavra-chave C # .
Guffa
32

Não, não há construção equivalente que permite que uma variável não inicializada seja passada para um método sem um aviso, mas, como mencionei na minha pergunta e resposta especificando um <Out()>atributo em uma ByRefdefinição de parâmetro, embora VB ignore isso, é tratado por C # como um outparâmetro.

Portanto, eu pré-inicializaria as variáveis ​​de referência para Nothing e especificaria <Out()> ByRefpara significar a intenção (isso funcionará se os usuários C # alguma vez acessarem seus métodos).

Se você sentir que sabe quando pretende acessar o padrão Nothingem variáveis ​​de referência não atribuídas, você pode definir a "Configuração de aviso" "Uso da variável antes da atribuição" para "Nenhum" no nível do projeto (Propriedades do projeto> Compilar, e provavelmente deseja definir a configuração para "Todas as configurações" antes de alterar esta configuração), ou, no VS2015 (VB.NET 14), você pode usar #Disable Warning BC42030.

Mark Hurd
fonte
3
Isso é significativo. Eu tinha uma subclasse VB de MembershipProvider e, em seguida, uma subclasse C # da subclasse VB. O código C # não estava reconhecendo o fato de que os métodos abstratos em MembershipProvider já haviam sido implementados até que eu apliquei o atributo na classe VB para parâmetros que foram especificados como fora da classe base MembershipProvider.
Richard Collette
@RichardCollette Provavelmente vale a pena responder à minha pergunta vinculada!
Mark Hurd,
9

Versão C #

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

Versão Vb.net

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

Encontrou a resposta aqui

Atualizar

Conforme declarado no comentário, não se esqueça de inicializar seu parâmetro que será usado no slot de saída

David
fonte
Em geral, concordo que ByRef é a coisa mais próxima do out . No entanto, ByRef ainda emitirá um aviso se você passar uma variável não inicializada, como a pergunta pede.
Richard
Meu voto negativo foi de um tempo atrás: o site ao qual você fez um link é muito geral; não lista questões específicas, diferenças e tecnicalidades. Além disso, sua resposta ainda não responde à pergunta.
Mark Hurd
1

Eu tive o problema no VB.NET que chamei uma função "por ref" que passou um array de volta.

Mesmo que o compilador tenha sinalizado isso como um aviso, tudo bem. A correção é super simples e provavelmente uma boa prática de programação.

eu mudei

Dim m_arr_values() as Integer

fnRetArray(m_arr_values)

para

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

fnRetArray(m_arr_values)

Também ajuda na codificação se os nomes das variáveis ​​forem descritivos ...

Sub fnCreatePalette(ByRef arr_in_pal() As color, ByRef arr_out_pal() as uinteger)
    ...
End Sub
TheWhitde
fonte
3
A notação húngara é contra as diretrizes de design do .NET framework.
Gqqnbig 01 de
0

Você pode usar o método de passagem por referência em VB.NET.

Você precisa do mecanismo de parâmetro Out em C #, porque ele não permite que você use nenhuma variável sem inicializá-la.

O VB.NET não precisa de uma palavra-chave especial, pois ele o faz automaticamente.

Basta usar ByRef.

Josh
fonte
3
Isso não responde à pergunta e está errado em relação ao C #.
cspolton
O byref permite que você não inicialize e permite que você altere o valor dos parâmetros. Mas, ao contrário do parâmetro C # out, PERMITE que você inicialize o parâmetro com um valor e o use na função, enquanto em C # a palavra-chave out força você a usar SOMENTE como um parâmetro de saída e NÃO como entrada para a função. Além disso, se você não alterar ou definir um valor para este parâmetro dentro de sua função, o compilador não irá interpretar isso como um erro, ao contrário do C #, onde um erro de compilação será emitido.
pashute
0

O VB tem o atributo que deve ser igual ao C # out, mas hoje você ainda recebe um aviso mesmo se usá-lo. Existem detalhes sobre como consertá-lo na área vblang do github. https://github.com/dotnet/vblang/issues/67 .

Paul Cohen
fonte
-5

Use a palavra-chave ByRef antes da variável.

deostroll
fonte
4
ByRefé equivalente a refparâmetros em C #, que precisam ser inicializados antes de serem transmitidos para uma função.
cspolton