BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Notícias O futuro do C#: Tuplas e estruturas anônimas

O futuro do C#: Tuplas e estruturas anônimas

Com o C# 6 próximo de sua conclusão, começam os planos para o C# 7. Neste momento nada ainda é definitivo, mas já se iniciou a categorização de propostas nos termos de "interesse e plausibilidade estimada". Nesta série, vamos abordar algumas das propostas iniciando com o suporte da linguagem à tuplas.

O propósito de uma tupla é criar uma forma leve de retornar múltiplos valores de uma função. Um bom suporte a tuplas elimina a necessidade de parâmetros de saída (out parameter), que são frequentemente considerados por serem confusos. Além disso, parâmetros de saída são incompatíveis com o modelo async/await, tornando-os inúteis em muitos cenários.

E a classe Tuple?

O .NET Framework possui uma classe Tuple desde sua versão 4. Entretanto, a maioria dos desenvolvedores a considera útil somente em algumas situações bem limitadas. Para começar, Tuple é uma classe. Isso significa que é necessário alocar memória para sua utilização, o que por sua vez adiciona pressão à memória e torna os ciclos de coleta de lixo (garbage collection) mais frequentes. Para competir com parâmetros de saída em termos de desempenho, a classe Tuple precisava ser uma estrutura (struct).

O segundo problema envolve o design da API. Se visualizar um tipo de retorno como Tuple<int, int>, isto pode não ter muito significado. A cada uso da função será necessário checar a documentação duas vezes, uma quando estiver escrevendo o código e outra durante sua revisão. Seria muito mais útil se o tipo de retorno fosse algo como Tuple<int count, int sum>.

Estruturas anônimas

Considere as seguintes linhas de código:

public (int sum, int count) Tally(IEnumerable values) { ... }
var t = new (int sum, int count) { sum = 0, count = 0 };

Na nova proposta, cada linha define um novo tipo de valor anônimo com as propriedades sum e count. Observe que, de forma diferente de uma classe anônima, uma estrutura anônima precisa listar explicitamente os tipos e nomes da propriedades.

Uma vantagem de utilizar estruturas (structs) é que elas definem os métodos Equals e GetHashCode automaticamente. Ainda que alguém possa argumentar que a implementação padrão não é muito eficiente e que o compilador deveria prover uma implementação alternativa.

Desempacotando Tuplas

Uma parte importante da proposta de tuplas é a habilidade de desempacota-las com uma única linha de código. Considere este bloco de código:

var t = Tally(myValues);
var sum = t.Sum;
var count = t.Count;

Com o desempacotamento, ele se torna simplesmente:

(var sum, var count) = Tally(myValues);

Ainda não foi decidido se pode-se ou não desempacotar uma tupla sem declarar novas variáveis. Em outras palavras, não foi decidido se pode omitir 'var' e usar uma variável pré-existente em seu lugar.

Retornando Tuplas

Existem duas propostas sendo consideradas para definir como as tuplas devem ser retornadas de uma função. A primeira delas é bem simples de se entender:

return (a, b);

A segunda proposta não utiliza uma instrução return. Considere este exemplo:

A segunda proposta não utiliza uma instrução return. Considere este exemplo:

public (int sum, int count) Tally(IEnumerable values)
{
	sum = 0; count = 0;
	foreach (var value in values) { sum += value; count++; }
}

Variáveis locais e de retorno implicitamente criadas não representam um novo conceito. O Visual Basic foi originalmente projetado desta maneira, apesar dela cair em desuso desde que o VB 7 introduziu a instrução return. Ela também espelha o que seria escrito se estivesse trabalhando com parâmetros de saída. Ainda assim, a não utilização de uma instrução return seria algo desconcertante para muitos desenvolvedores.

Outras dificuldades

O suporte a tuplas é um tópico bastante complexo. Embora este artigo cubra os aspectos do dia-a-dia, muitos detalhes terão de ser resolvidos da perspectiva dos usuários avançados e dos criadores do compilador.

As tuplas devem ser mutáveis? Isto pode ser útil do ponto de vista de desempenho ou conveniência, mas também pode tornar o código mais propenso a erros, especialmente quando tratamos de código multi-thread.

As tuplas devem ser unificadas entre assemblies? Tipos anônimos não são unificados, mas de forma distinta dos tipos anônimos, as tuplas seriam expostas como parte de uma API.

Tuplas podem ser convertidas em outras tuplas? Superficialmente, se elas tiverem a mesma estrutura de tipos, mas nomes diferentes de propriedades. Ou os mesmos nomes de propriedades e tipos mais amplos de propriedades.

Se passar uma tuplas de dois valores para uma função que receba dois parâmetros, a tupla será automaticamente desempacotada? Por outro lado, pode-se empacotar um par de argumentos em um parâmetro do tipo tupla?

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT