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 12

Lançado em novembro de 2023

Os seguintes recursos foram adicionados no C# 12:

E Interceptores – foi lançado como Versão prévia do recurso.

No geral, o C# 12 fornece novos recursos que tornam você mais produtivo ao escrevercódigo C#. A sintaxe que você já conhecia está disponível em mais locais. Outra sintaxe permite consistência para conceitos relacionados.

C# versão 11

Lançado em novembro de 2022

Os seguintes recursos foram adicionados em C# 11:

O C# 11 apresenta matemática genérica e vários recursos que dão suporte a essa meta. Você pode escrever algoritmos numéricos uma vez para todos os tipos de número. Há mais recursos para facilitar o trabalho com os tipos de struct, como membros necessários e structs de padrão automático. O trabalho com cadeias de caracteres fica mais fácil com literais de cadeia de caracteres brutas, nova linha em interpolações de cadeia de caracteres e literais de cadeia de caracteres UTF-8. Recursos como os tipos de locais de arquivo permitem que os geradores de origem sejam mais simples. Por fim, os padrões de lista adicionam mais suporte para correspondência de padrões.

C# versão 10

Lançado em novembro de 2021

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

Mais recursos estavam disponíveis no modo de visualização. 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 expressar 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.

C# versão 9

Lançado em novembro de 2020

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:

O C# 9 inclui novas melhorias de correspondência de padrões:

  • Padrões de tipo correspondem a um objeto correspondente a um tipo específico
  • Padrões entre parênteses impõem ou enfatizam a precedência de combinações de padrões
  • Padrões conjuntivos and exigem que ambos os padrões correspondam
  • Padrões conjuntivos or exigem que ambos os padrões correspondam
  • Padrões conjuntivos not exigem que ambos os padrões correspondam
  • Os padrões relacionais exigem que a entrada seja menor que, maior que, menor ou igual ou maior que ou igual a uma determinada constante

Esses padrões enriquecem a sintaxe para padrões. Considere estes exemplos:

public static bool IsLetter(this char c) =>
    c is >= 'a' and <= 'z' or >= 'A' and <= 'Z';

Com parênteses opcionais para deixar claro que and tem precedência maior que or:

public static bool IsLetterOrSeparator(this char c) =>
    c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or '.' or ',';

Um dos usos mais comuns é uma nova sintaxe para uma verificação nula:

if (e is not null)
{
    // ...
}

Qualquer um desses padrões pode ser usado em qualquer contexto em que os padrões são permitidos: expressões de padrão is, expressõesswitch, padrões aninhados e o padrão de uma instrução switch do rótulo case.

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.

Desempenho e interoperabilidade

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.

Ajustar e concluir recursos

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 8.0

Lançado em setembro de 2019

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 Common Language Runtime (CLR), outros, de tipos de biblioteca adicionados somente no .NET Core. O 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 7.3

Lançado em maio de 2018

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 implementadas automaticamente.
  • 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 7.2

Lançado em novembro de 2017

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.
  • private protectedmodificadores de acesso:
    • 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.1

Lançado em agosto de 2017

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.
  • default Expressões literais
    • 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.0

Lançado em março de 2017

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. Aqui estão alguns dos novos recursos:

Outros recursos incluíam:

Todas essas funcionalidades oferecem novos recursos 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. 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 6.0

Lançado em julho de 2015

A versão 6.0, lançada com o Visual Studio 2015, trouxe 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

Mas, se você os observar em conjunto, verá um padrão interessante. Nesta versão, o C# começou a eliminar 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 5.0

Lançado em agosto de 2012

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:

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.

C# versão 4.0

Lançado em abril de 2010

O C# versão 4.0, lançado com o Visual Studio 2010, 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 3.0

Lançado em novembro de 2007

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. O melhor recurso dessa versão do C# era a expressão de consulta, também conhecida como Consulta Integrada à Linguagem (LINQ).

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 tornou uma lista de inteiros muito mais inteligente.

C# versão 2.0

Lançado em novembro de 2005

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 orientada a objeto (OO) genérica, a versão 2.0 do C# tratou de mudar isso rapidamente. 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.

C# versão 1.2

Lançado em abril de 2003

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 1.0

Lançado em janeiro de 2002

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:

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