Inquiridor
ByRef e ByVal quando usar

Discussão Geral
-
Li que certos tipos é aconselhável que sejam passados por referência pois tem uma melhor performance. Mesmo principio de C++
Mas na prática quais são esse tipos?
Por exemplo eu tenho optador por usar ByRef para objetos próprios (minhas classes), Listas List(Of..), e Date. Está certo essa minha escolha? Algum à acrescentar ou retirar?
- Editado Matheus S. Silva quarta-feira, 13 de abril de 2016 21:00
- Tipo Alterado Marcos SJ quinta-feira, 14 de abril de 2016 10:52
Todas as Respostas
-
Bom dia Matheus S. Silva,
Quanto as suas características:
Especifica que um argumento é passado de tal forma que o procedimento chamado pode alterar o valor de uma variável subjacente ao argumento no código de chamada.
Especifica que um argumento é passado de tal forma que o procedimento ou propriedade chamado não pode alterar o valor de uma variável subjacente ao argumento no código de chamada.
Mas para entender melhor entender quando usar cada um peço que examine as informações contidas nos seguintes links:
Entendendo Passagem por Valor e por Referência (Byval/ByRef)
Passing Variables By Reference And By Value
Espero ter ajudado.
Atenciosamente
Marcos SJ
Esse conteúdo e fornecido sem garantias de qualquer tipo, seja expressa ou implícita
MSDN Community Support
Por favor, lembre-se de Marcar como Resposta as postagens que resolveram o seu problema. Essa é uma maneira comum de reconhecer aqueles que o ajudaram e fazer com que seja mais fácil para os outros visitantes encontrarem a resolução mais tarde.
- Editado Marcos SJ quinta-feira, 14 de abril de 2016 11:07
-
Matheus, primeiro veja tudo o que o Marcos postou - são links sobre o assunto e é bom para você entender melhor.
De uma forma "resumida", ao você passar um argumento ByVal para um método, o método tem o VALOR da variável; basicamente é como se você fizesse isso:
int ABC = 1; int CDE = ABC;
Você entregou ao argumento do método o valor da variável passada. Dessa forma, se a variável for uma STRUCT, toda e qualquer alteração feita nela, pelo método, não será passado para a variável original. Veja:
public class Test { int Abc = 1; public void Method(int Cde) { Cde++; } public void Run() { this.Method(this.Abc); //Abc continua 1, porque o método adicionou 1 no Cde //mas o Cde não tem vínculo com Abc } }
Então neste caso você PRECISA usar ByRef, se você for usar este método ele deveria ser Ref, para retornar o valor alterado.
Uma classe no entanto, pode ser ByVal, porque o VALOR da classe não é o conteúdo da classe, apenas a referência ao endereço onde ela está na memória. Por isso, se você tem uma classe ela ocupa um espaço na memória e a variável a qual ela está associada não guarda os bytes da classe, mas sim um endereço de 64bit aonde a classe (e suas variaveis, métodos etc) está guardada. Quando você atualiza uma propriedade (ou variável) da classe, a referencia permanece a mesma. Algo assim:
public class Filho { string Nome; public Filho() { } public Filho(string Nome) { this.Nome = Nome; } } public class Test { Filho Abc = new Filho("Eu"); //neste momento, foi alocado na memória um espaço para //o conteúdo da classe filho. Esse espaço tem um endereço //o valor contido em Abc não é "Eu" mas 0x000001231411 //(exemplo), onde a classe está. public void Method(Filho Cde) { Cde.Nome += " Não"; } public void Run() { this.Method(this.Abc); //Abc continua 0x000001231411 //mas Abc.Nome mudou, pois Cde e Abc eram ambos //ponteiros para o mesmo endereço de memória que //armazena a instância de Filho() criada em Abc } }
Espero não ter confundido mais ... rsrsrs
EDIÇÃO
Complementando. Seguindo este exemplo, se você fizer:
public void Method(Filho Cde) { Cde = new Filho("Outro"); }
A variável "Abc" vai continuar sendo "Filho(Eu)". Porque você trocou o valor (referência) de Cde para uma nova instância, mas "Abc" continua vinculada. No entanto, se o método fosse ByRef:
public void Method(ref Filho Cde) { Cde = new Filho("Outro"); }
Então "Abc" passaria a ser "Filho(Outro)" ao invés de "Filho(Eu)". Porque com REF, você alterou o valor de "Cde", vinculado a "Abc". O valor DA CLASSE (o endereço 0x000001231411) onde ela está.
- Editado SammuelMiranda quinta-feira, 14 de abril de 2016 12:06 Complemento
-
Eu conheço as questões que envolvem alocação de memória e variáveis por referência e valor. Programei muito em C/C++ no passado. E até onde sei, quando uma variável é passada por valor o conteúdo dela é copiado pela função, ou seja o conteúdo é duplicado, e dependendo do tamanho do seu objeto isso pode ser dispendioso do ponto de vista de performance.
A a biblioteca MSDN aconselha ByRef para tais elementos.
https://msdn.microsoft.com/en-us/library/ddck1z30.aspx#Anchor_1https://msdn.microsoft.com/pt-br/library/ddck1z30.aspx#Anchor_1
O motivo do meu tópico é mais para tratar de performance e não do conceito.