C# e .NET

O que é C#?

C# foi desenvolvido exclusivamente para a plataforma .NET Framework da Microsoft e sua pronúncia é “See Sharp”.

A Microsoft precisava de uma estrutura de desenvolvimento integrada, unificada e totalmente orientada a objetos para eliminar os defeitos das tecnologias antigas. Com esse objetivo, começou a criar um novo ambiente de execução de código, aliado a uma cadeia completa de ferramentas de desenvolvimento.

Após mais de 20 anos de evolução, o C# deixou de ser uma linguagem restrita ao Windows para se tornar uma linguagem multiplataforma compatível com diversos sistemas operacionais.

Atualmente, o C# junto ao .NET formam uma solução multiplataforma completa: é possível desenvolver aplicações para Windows, macOS, Linux e Android. Além disso, ele é o ambiente de execução preferido para a maioria dos sistemas em nuvem.

Graças ao forte investimento da Microsoft, o C# recebe atualizações constantes e rápidas. Em 2022 foi lançada a versão 7. O C# mantém compatibilidade com códigos escritos há 20 anos, enquanto as versões novas contam com uma sintaxe mais concisa, elegante e estruturas mais compactas. Em 2026, a versão atual é a 15ª edição.

Breve cronologia das versões do C# (trecho)

  • C# 1.0 (2001): lançamento público oficial
  • C# 2.0 (VS2005): genéricos, iteradores, métodos anônimos
  • C# 3.0 (VS2008): métodos de extensão, expressões Lambda, LINQ (Consulta Integrada à Linguagem)
  • C# 4.0 (2010): parâmetros nomeados/opcionais, tipo dinâmico dynamic, biblioteca de tarefas paralelas TPL para aproveitar todo o potencial dos processadores multinúcleo
  • C# 5.0: suporte nativo a tarefas assíncronas com async/await
  • C# 6.0: interpolação de strings, membros com corpo de expressão, sintaxe simplificada para propriedades
  • C# 7.0~7.3: múltiplos valores de retorno por tuplas, simplificação de parâmetros out, casamento de padrões, método Main assíncrono
  • C# 8.0/9.0/10.0: registros (tipos de referência imutáveis), instruções de nível superior (sem necessidade de Main), métodos padrão de interface, funções locais estáticas, tipos descartáveis assíncronos, casamento de padrões em todo o escopo da linguagem
  • C#11 (.NET7): strings brutas, matemática genérica, propriedades required
  • C#12 (.NET8): construtores principais, sintaxe abreviada para coleções, vetores em linha
  • C#13 (.NET9): propriedades parciais, indexadores de extensão, variáveis ref locais em iteradores
  • C#14 (.NET10): aliases genéricos, casamento profundo de coleções, açúcar sintático SIMD

O Windows continua sendo a plataforma principal do C#, mas graças ao Runtime do .NET, o código pode ser executado diretamente em sistemas como o Linux. Isso possibilita escrever uma única base de código para implantá-la em vários sistemas operacionais.

O .NET Framework

O .NET Framework foi lançado pela primeira vez em 2002.

O .NET Framework resolve os limites das gerações antigas de desenvolvimento e conta com os seguintes pontos fortes centrais:

  1. Suporte a múltiplos dispositivos: funciona em servidores, computadores, PDAs, celulares e outros hardwares;
  2. Conformidade com padrões da indústria: suporte nativo a protocolos de comunicação universais como XML, HTTP, SOAP, JSON e WSDL;
  3. Sandbox de segurança: cria um isolamento seguro para executar códigos de fontes não confiáveis.

Os três componentes centrais do .NET Framework

  1. CLR Common Language Runtime (ambiente de execução) controla todo o ciclo de vida dos programas: gerenciamento de memória e coleta de lixo, validação de segurança do código, agendamento de threads e tratamento de exceções.
  2. Conjunto de ferramentas de desenvolvimento ambientes de desenvolvimento integrados, compiladores .NET multilinguagem (C#/VB.NET/F#, entre outros), depuradores e tecnologias de backend web como ASP.NET/WCF.
  3. BCL Biblioteca de Classes Base (também chamada de FCL Framework Class Library) conta com uma vasta quantidade de classes genéricas pré-implementadas que o desenvolvedor pode invocar diretamente.

Diferenciais de atualização do .NET em comparação ao desenvolvimento tradicional para Windows

Sistema orientado a objetos unificado

O CLR, a BCL e o C# são profundamente integrados e entregam um modelo OOP unificado. Aplicativos de desktop, mobile, web e sistemas distribuídos compartilham o mesmo paradigma de desenvolvimento, com sintaxe e lógica consistentes em qualquer dispositivo.

Coleta automática de lixo GC

O CLR traz um coletor de lixo nativo que libera automaticamente a memória de objetos que não são mais utilizados. O desenvolvedor não precisa liberar memória manualmente nem rastrear vazamentos de memória, reduzindo muito o trabalho de manutenção.

Interoperabilidade multidimensional
  1. Comunicação entre linguagens .NET: classes escritas em linguagens .NET distintas podem se chamar e herdar mutuamente; a plataforma não está vinculada a uma única linguagem de programação;
  2. Invocação de plataforma P/Invoke: permite chamar diretamente interfaces de DLL nativas Win32 escritas em C;
  3. Compatibilidade com COM: componentes .NET e componentes COM legados podem ser invocados em ambos os sentidos.

Implantação simplificada: não depende de registro do sistema; em cenários mínimos basta copiar os arquivos para executar o programa;

Montagens paralelas: várias versões de uma mesma DLL podem coexistir em um dispositivo. Cada programa fica vinculado à versão da biblioteca com a qual foi compilado, resolvendo conflitos de versão de DLL.

Validação de segurança de tipos O CLR (Common Language Runtime) valida obrigatoriamente parâmetros e tipos de dados. Mesmo na interação entre componentes de linguagens diferentes, ele garante a segurança de tipos e bloqueia acessos ilegais à memória.

Ampla Biblioteca de Classes Base BCL

Várias classes utilitárias genéricas já vêm implementadas nativamente

  • Ferramentas básicas para manipulação de arquivos, strings, criptografia e segurança;
  • Contêineres de coleções: listas, dicionários, tabelas hash;
  • Ferramentas de multithreading, sincronização e concorrência;
  • Classes para leitura e gravação de documentos XML
  • E muitos outros recursos…

Toda a lógica de baixo nível genérica já está pronta, então o desenvolvedor só precisa implementar a lógica exclusiva do negócio. Reutilizar ferramentas prontas evita reinventar a roda.

Diagrama de fluxo de um programa .NET: o código que você escreve é compilado para a linguagem intermediária IL. O IL pode chamar bibliotecas disponibilizadas pela BCL e, por fim, é entregue ao CLR para execução.

Relação entre C# e .NET

.NET Framework: uma plataforma completa de desenvolvimento e execução, composta por dois componentes centrais

  1. CLR (Common Language Runtime): responsável pelo gerenciamento de memória do código, execução e validações de segurança
  2. BCL (Biblioteca de Classes Base): conjunto massivo de código utilitário genérico (arquivos, rede, interface gráfica, concorrência e muito mais)

C#: uma linguagem de programação projetada especialmente para a plataforma .NET, usada para escrever códigos que rodam sobre o CLR

Além do C#, outras linguagens de programação também suportam o .NET, como F# e VB.NET.

O objetivo principal do .NET Framework é ser multiplataforma e multilinguagem. Multiplataforma significa funcionar em diferentes sistemas operacionais; multilinguagem significa que componentes desenvolvidos em linguagens distintas podem acessar uns aos outros.

Compilação para Linguagem Intermediária Comum (CIL)

O compilador de cada linguagem .NET lê os arquivos de código-fonte e gera arquivos de saída chamados montagens (assembly)

Existem dois tipos de montagens: arquivos executáveis (exe) ou bibliotecas de ligação dinâmica (DLL)

O código interno de uma montagem não é código de máquina nativo do processador, mas sim um código intermediário chamado Linguagem Intermediária Comum (Common Intermediate Language, CIL).

Uma montagem contém principalmente os seguintes elementos:

  1. Instruções de código CIL do programa
  2. Metadados de todos os tipos presentes no programa
  3. Metadados com as relações de referência para outras montagens externas

A abreviação da linguagem intermediária mudou ao longo do desenvolvimento do .NET, por isso materiais diferentes usam nomes variados. Tanto Linguagem Intermediária (IL) quanto Linguagem Intermediária da Microsoft (MSIL) se referem ao CIL.

Compilação para código nativo e execução

O CIL não é convertido antecipadamente para código de máquina nativo; apenas no momento da execução do programa, o CLR executa estes três passos:

  1. Validar as informações de segurança da montagem
  2. Alocar memória para execução
  3. Enviar ao compilador JIT para compilar fragmentos em código nativo
Mecanismo de compilação sob demanda JIT

Apenas o código que for executado é compilado, e após a compilação ele é armazenado em cache para reutilização. Códigos nunca invocados não passam por compilação, e o mesmo trecho de código é compilado apenas uma única vez.

Montagem (CIL + informações de tipos) → CLR (compilador JIT) → Código nativo → Serviços do sistema operacional

Responsabilidades de gerenciamento do CLR

Após a conversão do CIL em código nativo, o CLR gerencia automaticamente: coleta de memória inutilizada, verificação de limites de vetores, validação de tipos de parâmetros e tratamento de exceções.

Código gerenciado e não gerenciado
  • Código gerenciado: códigos escritos em linguagens .NET, cuja execução e controle dependem do CLR
  • Código não gerenciado: não está sob o controle do CLR, exemplos são DLL nativas Win32 desenvolvidas em C/C++

Atualmente a Microsoft conta com compilação AOT: é possível compilar diretamente o código C# para código nativo, de forma similar ao C++. Assim, basta rodar o arquivo EXE sem a necessidade de instalar o runtime do .NET.

Ferramenta NGen

Realiza uma pré-compilação offline das montagens para imagens nativas. Durante a execução, o passo de compilação JIT é ignorado, acelerando o tempo de inicialização do aplicativo.

O .NET Core AOT é a nova geração de pré-compilação, capaz de gerar executáveis nativos independentes, sem dependências de runtime.

Montagem (Informações de tipo, CIL)
        ↓
Compilador JIT
        ↓
Código nativo
        ↓
Serviços do Sistema Operacional
Code language: JavaScript (javascript)

Independentemente da linguagem original do código-fonte, todos seguem o mesmo fluxo de compilação e execução.

Cada linguagem tem seu próprio compilador: o VB.NET tem o compilador específico para VB, o C# tem o compilador do C#. Todos convertem seus códigos para CIL, o CIL passa pelo JIT para gerar código nativo e esse código é executado pelo processador. Essa é a razão pela qual softwares desenvolvidos em .NET exigem a instalação do ambiente .NET, assim como o Java precisa do JRE.

flowchart TD
    subgraph Compile_Time
        A[C# Source] --> B[C# Compiler]
        B --> C[Assembly CIL]
        D[VB Source] --> E[VB Compiler]
        E --> C
        F[Xyz.NET Source] --> G[Xyz.NET Compiler]
        G --> C
    end

    subgraph Run_Time
        C --> H[JIT Compiler]
        H --> I[Native Code]
        I --> J[Operating System Services]
    end

O diagrama acima mostra o fluxo completo de compilação e execução para todas as linguagens.

Common Language Runtime (CLR)

O componente central do .NET Framework é o CLR, que fica sobre o sistema operacional e cuida de todo o gerenciamento da execução dos programas.

  • Coleta automática de lixo (GC)
  • Validação de segurança e autenticação por meio da Biblioteca de Classes Base (BCL)
  • Oferece amplas capacidades de programação, incluindo serviços web, serviços de dados e outras funcionalidades
flowchart TD
    subgraph Unmanaged_Code
        A[Non-.NET Program] --> OS[Operating System]
    end

    subgraph Managed_Code
        B[Assembly] --> CLR[Common Language Runtime]
        C[Assembly] --> CLR
        D[Assembly] --> CLR

        subgraph CLR[Common Language Runtime]
            M[Memory Management] --- E[Exception Handling]
            G[Garbage Collection] --- R[Reflection Services]
            J[JIT Compiler] --- L[Class Loader]
            S[Security Services]
        end

        CLR --> OS
    end

Infraestrutura Comum de Linguagem (CLI)

Cada linguagem de programação traz um conjunto nativo de tipos básicos para representar números inteiros, números de ponto flutuante, caracteres e outros dados.

Infraestrutura Comum de Linguagem (CLI) é um conjunto de padrões que unifica todos os componentes do .NET Framework em um sistema completo e compatível.

Por exemplo, a quantidade de bits ocupada por um número inteiro é padronizada em todas as linguagens suportadas.

flowchart TD
    subgraph CLI[CLI]
        CLR[Common Language Runtime] --- CLS[Common Language Specification]
        BCL[Base Class Library] --- MDS[Metadata Definition & Semantics]
        CTS[Common Type System] --- CIL[Common Intermediate Language]
    end

A maioria dos desenvolvedores não precisa aprofundar todas as especificações da CLI, mas é fundamental dominar o Sistema Comum de Tipos CTS e a Especificação Comum de Linguagem CLS.

CTS Sistema Comum de Tipos

  • Conta com um conjunto padronizado de tipos de dados básicos, com propriedades fixas para cada um;
  • Todos os tipos próprios de cada linguagem .NET são mapeados para um subconjunto desses tipos padrão;
  • Todos os tipos herdam da classe raiz object;
  • O padrão unificado permite que tipos nativos do sistema e tipos definidos pelo usuário se comuniquem entre qualquer linguagem .NET.

CLS Especificação Comum de Linguagem

Define as regras unificadas que todas as linguagens compatíveis com o .NET devem seguir, cobrindo restrições de interação entre linguagens como tipos de dados, construtores de classes e passagem de parâmetros.

Diferenças entre .NET e .NET Framework

O .NET é a plataforma multiplataforma moderna da Microsoft, enquanto o .NET Framework é o runtime e bibliotecas legados restritos apenas ao Windows. Todas as funcionalidades novas são desenvolvidas apenas no .NET; o .NET Framework entrou em fase de manutenção e só recebe atualizações de segurança.

O .NET é multiplataforma e representa o foco principal de desenvolvimento da Microsoft. Todo o conteúdo seguinte deste material vai dar prioridade a ele.

Característica.NET.NET Framework
Suporte de plataformasMultiplataforma (Windows, Linux, macOS, contêineres, mobile via MAUI)Apenas Windows
StatusAtualizações contínuas (.NET 5 → .NET 10, lançamentos anuais com suporte LTS)Modo manutenção (4.8 é a versão final, apenas patches de segurança)
DesempenhoInicialização mais rápida, maior taxa de processamento, coleta de lixo otimizadaDesempenho mais antigo, dependente das APIs do Windows
Cenários de usoProjetos novos: API web, microsserviços, cloud native, desktop/mobile multiplataformaProjetos legados: Web Forms, WCF, Windows Workflow, entre outros
ImplantaçãoSuporte completo a Docker, contêineres e ambientes em nuvemNão suporta contêineres, depende de Windows Server
Linguagens suportadasC#, F#, VB.NET (multiplataforma)C#, VB.NET (apenas Windows)

As diferenças entre .NET e .NET Framework não são grandes. Ambos usam linguagens como C#, F# e VB.NET e mantêm uma sintaxe central idêntica. Na maioria dos casos, o mesmo código C# pode ser compilado e executado tanto no .NET Framework quanto no .NET (Core/5/6/7/8…).

A principal diferença reside na disponibilidade das bibliotecas de classes, e não na sintaxe.

Tecnologias presentes no .NET Framework como WCF, Web Forms e Windows Workflow foram removidas ou substituídas no .NET moderno.

No .NET foram adicionadas APIs modernas como Span<T>, ValueTask e Records, que não estão disponíveis no antigo .NET Framework.

Como o .NET Framework é exclusivo do Windows e o .NET é multiplataforma, algumas bibliotecas nativas do Windows foram removidas no .NET. Por exemplo, a System.Drawing funciona no Windows, mas na versão multiplataforma do .NET ela é marcada como compatível apenas com esse sistema operacional. Se você precisar de uma biblioteca de desenho no .NET, não pode usar a System.Drawing e terá que recorrer a bibliotecas de terceiros, como a SkiaSharp da Google.

Atenção: essas diferenças estão no nível da estrutura de framework; na camada da linguagem, como o C#, praticamente não há distinções. A sintaxe do C# que você escreve é idêntica em ambos os ambientes. A verdadeira diferença está nas bibliotecas de classes e no ambiente de execução, ou seja, o conjunto de APIs disponíveis é diferente.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *