O histórico da linguagem C#

Este artigo fornece um histórico de cada versão principal da linguagem C#. A equipe C# continua a inovar e a adicionar novos recursos. Os status detalhados do recurso de linguagem, incluindo os recursos considerados para as versões futuras, podem ser encontrados no repositório dotnet/roslyn no GitHub.

Importante

A linguagem C# depende de tipos e métodos nos quais a especificação C# é definida como uma biblioteca padrão para alguns dos recursos. A plataforma .NET fornece esses tipos e métodos em alguns pacotes. Um exemplo é o processamento de exceção. Cada instrução ou expressão throw é verificada para garantir que o objeto que está sendo gerado é derivado de Exception. Da mesma forma, cada catch é verificado para garantir que o tipo que está sendo capturado é derivado de Exception. Cada versão pode adicionar novos requisitos. Para usar os recursos de linguagem mais recentes em ambientes mais antigos, talvez seja necessário instalar bibliotecas específicas. Essas dependências estão documentadas na página de cada versão específica. Saiba mais sobre as relações entre linguagem e biblioteca para obter informações sobre essa dependência.

C# versão 1.0

Ao olhar para trás, a versão 1.0 de C#, lançada com o Visual Studio .NET 2002, ficou muito parecida com o Java. Como parte de suas metas de design declaradas para ECMA, ela procurou ser uma "linguagem simples, moderna e orientada a objetos para uso geral". Na época, parecer com Java significava que havia atingido essas metas de design iniciais.

Mas agora, se examinar novamente a C# 1.0, você poderá se sentir um pouco confuso. Carecia das funcionalidades assíncronas internas e algumas das funcionalidades relacionadas a genéricos que você nem valoriza. Na verdade, ela não tinha nada relacionado a genéricos. E a LINQ? Ainda não estava disponível. Essas adições levariam alguns anos para sair.

A versão 1.0 do C# parecia ter poucos recursos, em comparação com os dias de hoje. Você teria que escrever código um tanto detalhado. Mas, ainda assim, você poderia iniciar em algum lugar. A versão 1.0 do C# era uma alternativa viável ao Java na plataforma Windows.

Os principais recursos do C# 1.0 incluíam:

C# versão 1.2

C# versão 1.2 fornecida com o Visual Studio .NET 2003. Ele continha algumas pequenas melhorias na linguagem. Muito notável é que, a partir desta versão, o código gerado em um loop foreach chamou Dispose, em um IEnumerator, quando o IEnumerator implementou IDisposable.

C# versão 2.0

Neste momento, as coisas começam a ficar interessantes. Vamos dar uma olhada em alguns recursos principais do C# 2.0, lançado em 2005, junto com o Visual Studio 2005:

Outros recursos do C# 2.0 adicionaram funcionalidades a recursos existentes:

  • Acessibilidade separada getter/setter
  • Conversões de grupo de método (delegados)
  • Classes estáticas
  • Inferência de delegado

Embora C# possa ter começado como uma linguagem OO (orientada a objeto) genérica, a versão 2.0 do C# tratou de mudar isso rapidamente. Depois de se acostumarem com a ideia da linguagem OO, os desenvolvedores começaram a sofrer com vários pontos problemáticos graves. E os procuraram de maneira significativa.

Com genéricos, tipos e métodos podem operar em um tipo arbitrário enquanto ainda mantêm a segurança de tipos. Por exemplo, ter um List<T> permite que você tenha List<string> ou List<int> e execute operações fortemente tipadas nessas cadeias de caracteres ou inteiros enquanto itera neles. Usar genéricos é melhor do que criar um ListInt que deriva de ArrayList ou converter de Object para cada operação.

A versão 2.0 do C# trouxe iteradores. Em resumo, o iteradores permitem que você examine todos os itens em um List (ou outros tipos Enumeráveis) com um loop foreach. Ter iteradores como uma parte importante da linguagem aprimorou drasticamente a legibilidade da linguagem e a capacidade das pessoas de raciocinar a respeito do código.

E ainda assim, o C# continuava na tentativa de alcançar o mesmo nível do Java. O Java já tinha liberado versões que incluíam genéricos e iteradores. Mas isso seria alterado logo, pois as linguagens continuaram a evoluir separadamente.

C# versão 3.0

O C# versão 3.0 chegou no final de 2007, juntamente com o Visual Studio 2008, porém o pacote completo de recursos de linguagem veio, na verdade, com o C# versão 3.5. Esta versão foi o marco de uma alteração significativa no crescimento do C#. Ela estabeleceu o C# como uma linguagem de programação realmente formidável. Vamos dar uma olhada em alguns recursos importantes nesta versão:

Numa retrospectiva, muitos desses recursos parecerem inevitáveis e inseparáveis. Todos eles se encaixam estrategicamente. Achavam que o melhor recurso dessa versão de C# era a expressão de consulta, também conhecida como LINQ (consulta integrada à linguagem).

Uma exibição mais detalhada analisa árvores de expressão, expressões lambda e tipos anônimos como a base na qual o LINQ é construído. Mas, de uma forma ou de outra, o C# 3.0 apresentou um conceito revolucionário. O C# 3.0 começou a definir as bases para transformar o C# em uma linguagem híbrida orientada a objeto e funcional.

Especificamente, agora você pode escrever consultas declarativas no estilo SQL para executar operações em coleções, entre outras coisas. Em vez de escrever um loop for para calcular a média de uma lista de inteiros, agora você pode fazer isso simplesmente como list.Average(). A combinação de expressões de consulta e métodos de extensão fez parecer que essa lista de inteiros se tornasse muito mais inteligente.

Levou algum tempo para que as pessoas entendessem e integrassem o conceito, mas isso aconteceu gradualmente. E agora, anos mais tarde, o código é muito mais conciso, simples e funcional.

C# versão 4.0

A versão 4.0 de C#, lançada com o Visual Studio 2010, enfrentou dificuldades para sobreviver ao status inovador da versão 3.0. Com a versão 3.0, o C# tirou verdadeiramente a linguagem da sombra do Java e a colocou em proeminência. A linguagem foi rapidamente se tornando elegante.

A próxima versão introduziu alguns novos recursos interessantes:

Tipos de interoperabilidade inseridos facilitaram os problemas de implantação da criação de assemblies de interoperabilidade COM para seu aplicativo. A contravariância e a covariância genérica oferecem maior capacidade para usar genéricos, mas eles são um tanto acadêmicos e provavelmente mais apreciados por autores de estruturas e bibliotecas. Os parâmetros nomeados e opcionais permitem eliminar várias sobrecargas de método e oferecem conveniência. Mas nenhum desses recursos é exatamente uma alteração de paradigma.

O recurso principal foi a introdução da palavra-chave dynamic. A palavra-chave dynamic introduziu na versão 4.0 do C# a capacidade de substituir o compilador na tipagem em tempo de compilação. Com o uso da palavra-chave dinâmica, você pode criar constructos semelhantes a linguagens dinamicamente tipadas, como JavaScript. Você pode criar um dynamic x = "a string" e, em seguida, adicionar seis a ela, deixando que o runtime decida o que acontece em seguida.

Associação dinâmica tem potencial de erros, mas também grande eficiência na linguagem.

C# versão 5.0

A versão 5.0 de C#, lançada com o Visual Studio 2012, era uma versão focada da linguagem. Quase todo o esforço para essa versão foi dedicado a outro conceito inovador de linguagem: os modelos async e await para programação assíncrona. Aqui está a lista dos recursos principais:

Consulte Também

O atributo de informações do chamador permite facilmente recuperar informações sobre o contexto no qual você está executando sem recorrer a uma infinidade de código de reflexão clichê. Ele tem muitos usos em diagnóstico e tarefas de registro em log.

Mas async e await são as verdadeiras estrelas dessa versão. Quando esses recursos foram lançados em 2012, o C# virou o jogo novamente, implantando a assincronia na linguagem como uma participante da maior importância. Se você já teve que lidar com operações de longa execução e a implementação de redes de retorno de chamada, você provavelmente adorou esse recurso de linguagem.

C# versão 6.0

Nas versões 3.0 e 5.0, o C# recebeu alguns novos recursos importantes em uma linguagem orientada a objeto. A versão 6.0, lançada com o Visual Studio 2015, abre mão de um recurso arrasador dominante lançando, em vez disso, muitos recursos menores que tornaram a programação em C# mais produtiva. Eis algumas delas:

Outros novos recursos incluem:

  • Inicializadores de índice
  • Await em blocos catch/finally
  • Valores padrão para propriedades somente getter

Cada um desses recursos é interessante em seus próprios méritos. Mas, se você os observar em conjunto, verá um padrão interessante. Nesta versão, o C# eliminou o clichê de linguagem para tornar o código mais conciso e legível. Portanto, para os fãs de código simples e conciso, essa versão da linguagem foi um grande benefício.

Fizeram ainda outra coisa com esta versão, embora não seja um recurso de linguagem tradicional em si. Lançaram Roslyn, o compilador como um serviço. Agora o compilador de C# é escrito em C#, e você pode usar o compilador como parte de seus esforços de programação.

C# versão 7.0

A versão 7.0 de C# foi lançada com o Visual Studio 2017. Esta versão tem algumas coisas interessantes e evolutivas na mesma direção que o C# 6.0, mas sem o compilador como um serviço. Aqui estão alguns dos novos recursos:

Outros recursos incluíam:

Todas essas funcionalidades oferecem novos recursos interessantes para desenvolvedores e a oportunidade de escrever um código mais limpo do que nunca. Um ponto alto é a condensação da declaração de variáveis a serem usadas com a palavra-chave out e a permissão de vários valores retornados por meio de tupla.

Mas o C# está sendo colocado para um uso cada vez mais amplo. Agora o .NET Core tem qualquer sistema operacional como destino e tem a visão firme na nuvem e na portabilidade. Essas novas funcionalidades certamente ocupam a mente e o tempo dos designers da linguagem, além de levarem a novos recursos.

C# versão 7.1

C# começou a lançar versões de ponto com C# 7.1. Essa versão adiciona a o elemento de configuração de seleção de versão da linguagem, três novos recursos de linguagem e um novo comportamento do compilador.

Os novos recursos de linguagem nesta versão são:

  • asyncMain método
    • O ponto de entrada para um aplicativo pode ter o modificador async.
  • Expressões literais default
    • Use expressões literais padrão em expressões de valor padrão quando o tipo de destino pode ser inferido.
  • Nomes de elementos de tupla inferidos
    • Em muitos casos, os nomes dos elementos de tupla podem ser inferidos com base na inicialização da tupla.
  • Restrições em parâmetros de tipo genérico
    • Você pode usar expressões de correspondência de padrão em variáveis cujo tipo é um parâmetro de tipo genérico.

Por fim, o compilador traz duas opções -refout e -refonly, que controlam a geração de assembly de referência

C# versão 7.2

C# 7.2 adicionou vários recursos de linguagem menores:

  • Inicializadores em matrizes stackalloc.
  • Uso de instruções fixed com qualquer tipo compatível com um padrão.
  • Acesso a campos fixos sem fixação.
  • Reatribuição de variáveis locais ref.
  • Declaração de tipos readonly struct, para indicar que uma struct é imutável e deve ser passada como um parâmetro in para seus métodos de membro.
  • Adição do modificador in em parâmetros, para especificar que um argumento seja passado por referência, mas não modificado pelo método chamado.
  • Uso do modificador ref readonly nos retornos de método, para indicar que um método retorna seu valor por referência, mas não permite gravações nesse objeto.
  • Declaração de tipos ref struct, para indicar que um tipo de struct acessa a memória gerenciada diretamente e deve sempre ser alocado por pilha.
  • Uso de restrições genéricas adicionais.
  • Argumentos nomeados que não estejam à direita
    • Os argumentos nomeados podem ser seguidos por argumentos posicionais.
  • Sublinhados à esquerda em literais numéricos
    • Agora os literais numéricos podem ter sublinhados à esquerda, antes dos dígitos impressos.
  • Modificador de acesso private protected
    • O modificador de acesso private protected permite o acesso a classes derivadas no mesmo assembly.
  • Expressões ref condicionais
    • O resultado de uma expressão condicional (?:) agora já pode ser uma referência.

C# versão 7.3

Há dois temas principais para a versão C# 7.3. Um tema fornece recursos que permitem que o código seguro tenha o mesmo desempenho que o código não seguro. O segundo tema fornece melhorias incrementais aos recursos existentes. Novas opções do compilador também foram adicionadas a essa versão.

Os novos recursos a seguir são compatíveis com o tema de melhor desempenho para código seguro:

  • Você pode acessar campos fixos sem fixação.
  • Você pode reatribuir variáveis locais ref.
  • Você pode usar inicializadores em matrizes stackalloc.
  • Você pode usar instruções fixed com qualquer tipo compatível com um padrão.
  • Você pode usar mais restrições genéricas.

Os seguintes recursos e aprimoramentos foram feitos nos recursos existentes:

  • Você pode testar == e != com tipos de tupla.
  • Você pode usar variáveis de expressão em mais locais.
  • Você pode anexar atributos ao campo de suporte de propriedades autoimplementadas.
  • A resolução de métodos quando os argumentos se diferenciam por in foi aprimorada.
  • A resolução de sobrecarga agora tem menos casos ambíguos.

As novas opções do compilador são:

  • -publicsign para habilitar a assinatura de Software de código aberto (OSS) de assemblies.
  • -pathmap para fornecer um mapeamento para diretórios de origem.

C# versão 8.0

C# 8.0 é a primeira grande versão em C# que tem como destino especificamente o .NET Core. Alguns recursos dependem de novos recursos de CLR, outros, de tipos de biblioteca adicionados somente no .NET Core. C# 8.0 adiciona os seguintes recursos e aprimoramentos à linguagem C#:

Os membros de interface padrão exigem aprimoramentos na CLR. Esses recursos foram adicionados na CLR para .NET Core 3.0. Intervalos e índices, além de fluxos assíncronos, exigem novos tipos nas bibliotecas do .NET Core 3.0. Tipos de referência anuláveis, implementados no compilador, são muito mais úteis quando bibliotecas são anotadas para fornecer informações semânticas sobre o estado nulo de argumentos e valores retornados. Essas anotações estão sendo adicionadas nas bibliotecas do .NET Core.

C# versão 9

C# 9 foi lançada com o .NET 5. É a versão de linguagem padrão para qualquer assembly direcionado à versão do .NET 5. Ela contém os seguintes recursos novos e aprimorados:

C# 9 continua três dos temas de versões anteriores: remoção da cerimônia, separação dos dados de algoritmos e fornecimento de mais padrões em mais lugares.

Instruções de nível superior significam que seu programa principal é mais simples de ler. Há menos necessidade de cerimônia: um namespace, uma classe Program e static void Main() são todos desnecessários.

A introdução de records fornece uma sintaxe concisa para tipos de referência que seguem semântica de valor para manter a igualdade. Você usará esses tipos para definir contêineres de dados que normalmente definem o comportamento mínimo. Os setters somente init fornecem o recurso de mutação não destrutiva (expressões with) nos registros. C# 9 também adiciona tipos de retorno covariantes para que os registros derivados possam substituir métodos virtuais e retornar um tipo derivado do tipo de retorno do método base.

Os recursos de padrões correspondentes foram expandidos de várias maneiras. Agora, os tipos numéricos dão suporte aos padrões de intervalo. Os padrões podem ser combinados usando padrões and, or e not. É possível adicionar parênteses para esclarecer padrões mais complexos.

Outro conjunto de recursos dá suporte à computação de alto desempenho em C#:

  • Os tipos nint e nuint modelam os tipos inteiros de tamanho nativo na CPU de destino.
  • Os ponteiros de função fornecem funcionalidade semelhante a delegado, evitando as alocações necessárias para criar um objeto delegado.
  • A instrução localsinit pode ser omitida para salvar instruções.

Outro conjunto de aprimoramentos dá suporte a cenários em que os geradores de código adicionam funcionalidade:

  • Inicializadores de módulo são métodos que o runtime chama quando um assembly é carregado.
  • Métodos parciais dão suporte a novos modificadores acessíveis e tipos de retorno não nulos. Nesses casos, uma implementação deve ser fornecida.

C# 9 adiciona muitos outros pequenos recursos que melhoram a produtividade do desenvolvedor, escrevendo e lendo código:

  • Expressões new de tipo de destino
  • Funções anônimas de static
  • Expressão condicional com tipo de destino
  • Suporte a GetEnumerator() de extensão para loops foreach
  • Expressões Lambda podem declarar parâmetros de descarte
  • Atributos podem ser aplicados a funções locais

A versão C# 9 continua o trabalho para manter C# uma linguagem de programação moderna e de uso geral. Os recursos continuam a dar suporte a cargas de trabalho e tipos de aplicativo modernos.

C# versão 10

C# 10 adiciona os seguintes recursos e aprimoramentos à linguagem C#:

Recursos adicionais estão disponíveis no modo versão prévia. Incentivamos você a experimentar esses recursos e fornecer comentários sobre eles. Eles podem mudar antes da versão final. Para usar esses recursos, você deve definir <LangVersion> como Preview em seu projeto:

C# 10 continua trabalhando em temas de remoção de cerimônia, separação de dados de algoritmos e aprimoramento do desempenho para o Runtime do .NET.

Muitos dos recursos significam que você digitará menos código para expressar os mesmos conceitos. Structs de registro sintetizam muitos dos mesmos métodos que as classes de registro. Structs e tipos anônimos dão suporte a expressões. Diretivas de uso global e declarações de namespace com escopo de arquivo significam que você expressa dependências e organização de namespace com mais clareza. Melhorias lambda facilitam a declaração de expressões lambda onde são usadas. Novos padrões de propriedade e melhorias de desconstrução criam um código mais conciso.

Os novos manipuladores de cadeia de caracteres interpolados e o comportamento AsyncMethodBuilder podem melhorar o desempenho. Esses recursos de linguagem foram aproveitados no .NET Runtime para obter aprimoramentos de desempenho no .NET 6.

C# 10 também marca uma mudança para a cadência anual de versões do .NET. Como nem todos os recursos podem ser concluídos em um período anual, você pode experimentar alguns recursos de "versão prévia" no C# 10. Os atributos genéricos e os membros abstratos estáticos em interfaces podem ser usados, mas eles são versões prévias do recurso e podem ser alterados antes da versão final.

Artigooriginalmente publicado no blog NDepend, cortesia de Erik Dietrich e Patrick Smacchia.