C#Usando os parâmetros ref e out


 Hoje vamos recordar o uso dos parâmetros ref e out na linguagem C#.

Na linguagem C#, por padrão, os parâmetros são passados para os métodos por valor. Podemos mudar esse comportamento usando as palavras-chave ref e out. Elas são usadas para passar argumentos dentro de um método ou função por referência.

Nota:  Os termos parâmetros e argumentos são frequentemente usados de forma intercambiáveis, embora eles tenham significados inteiramente diferentes.  Para esclarecer temos que :

Usando ref

Vamos iniciar com a palavra-chave ref que passa argumentos por referência o que significa que qualquer mudança feita nos argumentos no método irá se refletir nessa variável quando o controle retornar ao método de chamada.     

Vejamos o trecho de código a seguir:

using System;

namespace CShp_Ref_Out
{
    class Program
    {
        static void Main(string[] args)
        {
            int i = 1;
            Console.WriteLine("Valor anterior de i =" + i.ToString());
            string teste = GetProximoValor(ref i);
            Console.WriteLine("Valor atual de i = " + i.ToString());
            Console.ReadKey();
        }
        public static string GetProximoValor(ref int id)
        {
            string retorno = "Proximo-" + id.ToString();
            id += 1;
            return retorno;
        }
    }
}

O resultado obtido pela execução deste código será:

Observe que  i após o retorno da chamada do método possui o valor igual a 2 pois a chamada do método GetProximoValor(ref i) esta passando o argumento como referência e o seu valor esta sendo alterado no método e isso se reflete na variável i.

O modificador ref é para passar o argumento por referência, ou seja, em vez de passar o seu valor, passa-se um ponteiro que indica onde está o valor. Desta forma quando o parâmetro tiver alterado seu valor, estará alterando o valor do argumento já que eles estão na mesma posição de memória.

Usando out

A palavra-chave out também é usada para passar os argumentos por referência. Ele indica que o argumento a ser passado receberá um valor dentro do método. Ou seja, é uma referência também, mas não é passado nenhum valor para o parâmetro, é apenas uma forma de dar saída para um valor. Isto normalmente é necessário porque o return só pode ter um valor.

Dessa forma a palavra-chave out força os argumentos a serem passados por referência.  

Esse comportamento é idêntico ao da palavra-chave ref, exceto que ref requer que a variável seja inicializada antes de ser passada.   

Para usar um parâmetro com out, a definição do método e a chamada do método devem explicitamente usar a palavra-chave out.

Embora as variáveis passadas como argumentos out não precisem ser inicializadas antes de serem passadas, o método chamado deve atribuir um valor antes de o método retornar.

Neste exemplo vemos que o método MetodoA() usa o parâmetro out para passar o valor da variável a, atribuído no método, para fora do método.

using System;

namespace Out1
{
    class Program
    {
        static void Main(string[] args)
        {
            /* definição da variável local */
            int a = 100;

            Console.WriteLine($"Antes da chamada do método:  valor de a : {a}");

            /* chamando a função para obter o valor */
            getValor(out a);

            Console.WriteLine($"Depois da chamada do método, valor de a : {a}");
            Console.ReadLine();
        }
        public static void getValor(out int x)
        {
            int temp = 555;
            x = temp;
        }
    }
}

Resultado obtido:

Neste código temos que variável fornecida para o parâmetro de saída não necessita ter um valor atribuído.

Os parâmetros de saída são particularmente úteis quando você precisa retornar valores de um método através dos parâmetros sem atribuir um valor inicial para o parâmetro.

A seguir temos uma tabela comparando ref com out :

ref out
O parâmetro ou argumento deve ser inicializado antes de ser passado para ref Não é obrigatório inicializar um parâmetro ou argumento antes de ser passado para out.
   
Não é necessário atribuir ou inicializar o valor de um parâmetro (que é passado por ref) antes de retornar ao método de chamada No método chamado é necessário atribuir ou inicializar um valor de um parâmetro (que é passado para  out) antes de retornar ao método de chamada.
   
Passar um valor de parâmetro por ref é útil quando o método chamado também é necessário para modificar o parâmetro de passagem. Declarar um parâmetro para um método out é útil quando vários valores precisam ser retornados de uma função ou método.
   
Não é obrigatório inicializar um valor de parâmetro antes de usá-lo em um método de chamada Um valor de parâmetro deve ser inicializado no método de chamada antes de seu uso.
   
Quando usamos ref, os dados podem ser transmitidos bidirecionalmente. Quando usamos out, os dados são passados ​​apenas de forma unidirecional (do método chamado para o método do chamador).

Tanto ref como out são tratados de forma diferente em tempo de execução e são tratados da mesma forma em tempo de compilação.

E estamos conversados......

"Porém, respondendo Pedro e os apóstolos, disseram: Mais importa obedecer a Deus do que aos homens."
Atos 5:29

Referências:


José Carlos Macoratti