O uso da palavra-chave out está comumente associado à passagem de valores por referência. Em versões anteriores da linguagem C# há algumas implicações ao empregar este recurso:
- É preciso primeiramente declarar as variáveis a serem utilizadas em conjunto com este modificador. Isso acontece antes da chamada de um método com um ou mais parâmetros devolvidos como referência, não sendo necessário a inicialização das variáveis envolvidas (diferentemente da palavra-chave ref);
- Além disso, não é possível a utilização do modificador var na declaração das variáveis utilizadas.
A próxima listagem exemplifica o que foi descrito até aqui, com um exemplo de uso da palavra-chave out no método CalcularDiasVividos:
using System;
namespace ExemploOutVariables01
{
class Program
{
private static void CalcularDiasVividos(string strDataNasc)
{
DateTime dataNasc;
if (DateTime.TryParse(strDataNasc, out dataNasc))
{
DateTime dataAtual = DateTime.Now.Date;
Console.WriteLine(
quot;Data Atual: { dataAtual: dd/MM/yyyy}");
Console.WriteLine(
quot;Data de Nascimento: { dataNasc: dd/MM/yyyy}");
TimeSpan intervalo = dataAtual.Subtract(dataNasc);
Console.WriteLine(
quot;Quantidade de dias vividos: { intervalo.TotalDays}");
}
else
{
Console.WriteLine(quot;Data invalida: {strDataNasc}");
}
Console.Write(Environment.NewLine);
}
static void Main(string[] args)
{
CalcularDiasVividos("07/03/2017");
CalcularDiasVividos("ERRO");
CalcularDiasVividos("31/01/1990");
Console.ReadKey();
}
}
}
O C# 7.0 conta agora com um novo recurso conhecido como Out Variables, o qual foi concebido com o intuito de simplificar a passagem de valores por referência:
- Esta funcionalidade permite a declaração de uma variável no ponto em que a mesma é repassada como parâmetro, bastando apenas que se especifique o modificador out e o tipo a ser empregado para a variável;
- A variável declarada ao acionar um método poderá ser utilizada logo após o processamento deste último.
A listagem a seguir traz o exemplo anterior refatorado, de forma a demonstrar a utilização de uma Out Variable (neste caso a variável dataNasc, que foi declarada na chamada ao método CalcularDiasVividos):
using System;
namespace ExemploOutVariables01
{
class Program
{
private static void CalcularDiasVividos(string strDataNasc)
{
if (DateTime.TryParse(strDataNasc, out DateTime dataNasc)) // Out Variable
{
DateTime dataAtual = DateTime.Now.Date;
Console.WriteLine(
quot;Data Atual: { dataAtual: dd/MM/yyyy}");
Console.WriteLine(
quot;Data de Nascimento: { dataNasc: dd/MM/yyyy}");
TimeSpan intervalo = dataAtual.Subtract(dataNasc);
Console.WriteLine(
quot;Quantidade de dias vividos: { intervalo.TotalDays}");
}
else
{
Console.WriteLine(quot;Data invalida: {strDataNasc}");
}
Console.Write(Environment.NewLine);
}
static void Main(string[] args)
{
CalcularDiasVividos("07/03/2017");
CalcularDiasVividos("ERRO");
CalcularDiasVividos("31/01/1990");
Console.ReadKey();
}
}
}
A execução deste conjunto de instruções produzirá o seguinte resultado:
É possível ainda combinar o uso das palavras-chave out e var, como indicado na próxima listagem em outra variação do exemplo apresentado inicialmente:
using System;
namespace ExemploOutVariables01
{
class Program
{
private static void CalcularDiasVividos(string strDataNasc)
{
if (DateTime.TryParse(strDataNasc, out var dataNasc)) // Out Variable
{
DateTime dataAtual = DateTime.Now.Date;
Console.WriteLine(
quot;Data Atual: { dataAtual: dd/MM/yyyy}");
Console.WriteLine(
quot;Data de Nascimento: { dataNasc: dd/MM/yyyy}");
TimeSpan intervalo = dataAtual.Subtract(dataNasc);
Console.WriteLine(
quot;Quantidade de dias vividos: { intervalo.TotalDays}");
}
else
{
Console.WriteLine(quot;Data invalida: {strDataNasc}");
}
Console.Write(Environment.NewLine);
}
static void Main(string[] args)
{
CalcularDiasVividos("07/03/2017");
CalcularDiasVividos("ERRO");
CalcularDiasVividos("31/01/1990");
Console.ReadKey();
}
}
}
Conversões e validações correspondem a cenários nos quais o modificar out é utilizado com relativa frequência. Em situações deste tipo a declaração de variáveis empregadas apenas na invocação de um método constitui uma prática comum, conforme se observa no próximo exemplo (com a variável valor definida na operação EfetuarValidacao):
using System;
namespace ExemploOutVariables02
{
class Program
{
private static void EfetuarValidacao(string strValorInteiro)
{
int valor;
if (int.TryParse(strValorInteiro, out valor))
Console.WriteLine(quot;{strValorInteiro} é um número inteiro válido...");
else
Console.WriteLine(quot;{strValorInteiro} não é um valor inteiro...");
}
static void Main(string[] args)
{
EfetuarValidacao("1000");
EfetuarValidacao("057");
EfetuarValidacao("5.70");
Console.ReadKey();
}
}
}
Uma alternativa a fim de evitar a declaração de uma variável seria o uso de um discard, através do símbolo “_” (underline) empregado em conjunto com o modificador out:
using System;
namespace ExemploOutVariables02
{
class Program
{
private static void EfetuarValidacao(string strValorInteiro)
{
if (int.TryParse(strValorInteiro, out _)) // Utilizando um discard
Console.WriteLine(quot;{strValorInteiro} é um número inteiro válido...");
else
Console.WriteLine(quot;{strValorInteiro} não é um valor inteiro...");
}
static void Main(string[] args)
{
EfetuarValidacao("1000");
EfetuarValidacao("057");
EfetuarValidacao("5.70");
Console.ReadKey();
}
}
}
Ao executar este bloco de código teremos como resultado:
Não deixe de assistir a gravação de um hangout realizado recentemente pelo Canal .NET sobre este assunto:
Disponibilizei também no GitHub os diferentes exemplos apresentados durante a transmissão:
https://github.com/renatogroffe/CSharp7_VS2017







