Pesquisa

sexta-feira, 13 de fevereiro de 2009

Passagem de parâmetros

Em C#, os parâmetros podem ser passador por valor ou por referência. Passando parâmetros por referência permite que o método altere o valor do parâmetro passado e as mudanças persistem após a passagem do método.

Passando uma variavel do tipo Valor para um método significa passar uma cópia da variável para o método. Quaisquer alterações ao parâmetro que ocorrem no interior do método não tem nenhum efeito sobre os dados originais armazenadas na variável. Se você quiser que o chamado método para alterar o valor do parâmetro, você tem que passá-la por referência, usando a palavra ref.

Passagem de parâmetro tipo Valor, por Valor:

// PassingParams1.cs 
using System;
class PassingValByVal
{
static void SquareIt(int x)
// O parametro x é chamado por Valor.
// Alterações no x não afetarão o valor original do myInt.
{
x *= x;
Console.WriteLine("O valor antes de chamar o método: {0}", x);
}
public static void Main()
{
int myInt = 5;
Console.WriteLine("O valor antes de chamar o método: {0}",
myInt);
SquareIt(myInt); // Passing myInt by value.
Console.WriteLine("O valor após chamar o método: {0}",
myInt);
}
}
Saida:
O valor antes de chamar o método: 5
O valor dentro do método: 25
O valor após chamar o método: 5
Explicação: A variável myInt sendo um tipo de valor contém seus dados (o valor 5). Quando SquareIt é chamado, o conteúdo do myInt é copiado para o parâmetro x que é multiplicado por ele mesmo dentro do método. No Main porém, o valor de myInt é o mesmo, antes e depois de chamar o método SquareIt. Logo, a mudança que ocorre no interior do método afeta somente a variável local x.

Passagem de parâmetro tipo Valor, por Referencia:

// PassingParams2.cs 
using System;
class PassingValByRef
{
static void SquareIt(ref int x)
// O parametro x é passado por referencia.
// Alterações no x afetarão a conteudo do myInt.
{
x *= x;
Console.WriteLine("O valor dentro do método: {0}", x);
}
public static void Main()
{
int myInt = 5;
Console.WriteLine("valor antes de chamar o método: {0}",
myInt);
SquareIt(ref myInt); // Passing myInt by reference.
Console.WriteLine("O valor após chamar o método: {0}",
myInt);
}
}
Saida:
O valor antes de chamar o método: 5
O valor dentro do método: 25
O valor após chamar o método: 25
Neste exemplo, não é o conteudo de myInt que é passado, mas sim, uma referência à myInt. O parâmetro x não é um int, mas sim uma referência a um int (neste caso, uma referência à myInt). Portanto, quando x é multiplicado por ele mesmo dentro do método, o que realmente é multiplicado é o conteudo da variavel refenciada por x, no caso, myInt.

Passando de parâmetros do tipo Referência, por Valor:

// PassingParams4.cs 
// Passing an array to a method without the ref keyword.
using System;
class PassingRefByVal
{
static void Change(int[] arr)
{
arr[0]=888; // Essa alteraçao ocorre na variavel original.
arr = new int[5] {-3, -1, -2, -3, -4}; // Alteração somente local.
Console.WriteLine("Dentro do método, o primeiro elemento é: {0}", arr[0]);
}

public static void Main()
{
int[] myArray = {1,4,5};
Console.WriteLine("Dentro do Main, antes de chamr o método, o primeiro elemento é: {0}", myArray [0]);
Change(myArray);
Console.WriteLine("Dentro do Main, depois de chamr o método, o primeiro elemento é: {0}", myArray [0]);
}
}
Saida:
Dentro do Main, antes de chamr o método, o primeiro elemento é: 1
Dentro do método, o primeiro elemento é: -3
Dentro do Main, depois de chamr o método, o primeiro elemento é: 888
No exemplo anterior, a matriz, myArray que é um tipo Referência, ela é passada para o método sem o parâmetro ref. Nesse caso, uma cópia da referência, o que aponta para myArray é passada para o método. O resultado mostra que é possível que o método para alterar o conteúdo de um elemento matriz (de 1 a 888). No entanto, alocando uma nova parte de memória usando o operador new no interior do método Change faz com que a variável arr referência uma nova matriz. Assim, quaisquer alterações depois disso que não irá afetar a matriz original, myArray ,que foi criada no interior Main. Na verdade, duas matrizes são criadas neste exemplo, dentro do Main e uma no interior do método Change.

Passando de parâmetros do tipo Referência, por Referencia:


// PassingParams5.cs 
// Passando um array para um método utilizando ref.
// Compare com o exemplo anterior.
using System;
class PassingRefByRef
{
static void Change(ref int[] arr)
{
// As duas operaçoes alterarão o a variavel original.
arr[0]=888;
arr = new int[5] {-3, -1, -2, -3, -4};
Console.WriteLine("Dentro do método, o primeiro elemento é: {0}", arr[0]);
}

public static void Main()
{
int[] myArray = {1,4,5};
Console.WriteLine("Dentro principal, antes de chamar o método, o primeiro elemento é o seguinte: {0}", myArray [0]);
Change(ref myArray);
Console.WriteLine("Dentro principal, depois de chamar o método, o primeiro elemento é: {0}", myArray [0]);
}
}
Saida:
Dentro principal, antes de chamar o método, o primeiro elemento é o seguinte: 1
Dentro do método, o primeiro elemento é: -3
Dentro principal, depois de chamar o método, o primeiro elemento é: -3
Todas as mudanças que ocorrem no interior do método afeta a variavel original. De fato, o array original é reatribuídos usando o operador new. Assim, depois de chamar o método Change, qualquer referência a um dos ponto do myArray persistirá o valor alterado no método.

Mais informações:

http://msdn.microsoft.com/en-us/library/0f66670z(vs.71).aspx

http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx

http://msdn.microsoft.com/en-us/library/490f96s2.aspx

Créditos: Rodrigo Araujo, Márcio Martins, eu.

Nenhum comentário:

Postar um comentário