C# .NET: SDK, Runtime e CLR
O C# é a linguagem; o .NET é a plataforma que transforma o seu código em programa e o faz rodar. Quem procura "instalar C#" acaba instalando ".NET SDK", e nos tutoriais aparecem siglas como CLR, IL e JIT. Nesta aula você abre o .NET instalado no computador da Ana, vê o que tem dentro do arquivo que o compilador cria e assiste o .NET transformando o seu código em instruções do processador.
- A diferença entre o SDK (para quem programa) e o Runtime (para quem só roda programas).
- O que fazem o Roslyn (o compilador), a IL (a linguagem intermediária), o CLR (o motor) e o JIT (o tradutor de última hora).
- O que é a biblioteca de classes e de onde vem o
Console. - Como ver o que está instalado com
dotnet --list-sdksedotnet --list-runtimes. - O que são os arquivos
.dll,.pdbe.runtimeconfig.jsonque o build cria. - A diferença entre .NET, .NET Core, .NET Framework e Mono.
Todas as saídas desta aula vêm da máquina da Ana: Ubuntu 26.04 com o pacote dotnet-sdk-10.0 do próprio Ubuntu. Se você ainda não instalou o .NET, pode ler esta aula do mesmo jeito; a instalação vem logo depois, em Instalar no Linux.
A ideia: a receita em língua universal
Imagine uma rede de restaurantes com cozinhas no Brasil, no Japão e na Alemanha. A chef escreve as receitas em português, mas os cozinheiros de cada país falam línguas diferentes. Em vez de escrever três versões, a rede faz assim:
- Um tradutor oficial passa a receita do português para uma língua universal da rede, simples e exata, que todo cozinheiro da rede aprendeu.
- Em cada país, o cozinheiro lê a receita universal e, na hora de cozinhar, vai traduzindo cada passo para o jeito da cozinha dele, com os fogões e panelas que ele tem.
- Os ingredientes básicos (farinha, sal, ovos) já estão na despensa de toda cozinha da rede: a receita só diz "use farinha", sem explicar como fazer farinha.
O .NET funciona exatamente assim:
| No restaurante | No .NET | Nome técnico |
|---|---|---|
| A receita em português | O seu código C# | código-fonte (ola.cs) |
| O tradutor oficial | O compilador de C# | Roslyn |
| A receita na língua universal | O programa traduzido, guardado num arquivo .dll | IL (Intermediate Language, linguagem intermediária) |
| O cozinheiro de cada país | O motor que roda o programa naquele computador | CLR (Common Language Runtime) |
| Traduzir cada passo na hora de cozinhar | Transformar a IL em instruções do processador enquanto o programa roda | JIT (just-in-time, "bem na hora") |
| A despensa com os ingredientes básicos | Milhares de classes prontas: Console, Math, List, File… | biblioteca de classes (BCL) |
| Limpar a mesa quando o cliente vai embora | Recolher a memória que o programa não usa mais | coletor de lixo (GC, garbage collector) |
A grande vantagem: o mesmo arquivo .dll roda no Linux, no Windows e no macOS, em processadores Intel, AMD ou ARM. Quem se adapta a cada computador é o CLR, não o seu programa.
SDK e Runtime: as duas caixas do .NET
O .NET vem em dois tamanhos, para dois tipos de pessoa:
| Runtime ("tempo de execução") | SDK (Software Development Kit, "kit de desenvolvimento") | |
|---|---|---|
| Para quem | Quem só quer rodar programas prontos | Quem escreve programas: você |
| Tem dentro | O CLR, o JIT, o coletor de lixo e a biblioteca de classes | Tudo do Runtime, mais o compilador (Roslyn), o MSBuild (que organiza o build), os modelos de projeto e o comando dotnet run, dotnet new, dotnet build… |
| Pacote no Ubuntu | dotnet-runtime-10.0 | dotnet-sdk-10.0 |
| Número da versão | 10.0.12 | 10.0.112 |
Para seguir o guia, instale o SDK: ele já traz o Runtime junto. O comando dotnet mostra as duas coisas separadas:
$ dotnet --list-sdks « os SDKs instalados 10.0.112 [/usr/lib/dotnet/sdk] $ dotnet --list-runtimes « os Runtimes instalados Microsoft.AspNetCore.App 10.0.12 [/usr/lib/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 10.0.12 [/usr/lib/dotnet/shared/Microsoft.NETCore.App]
- 10.0.112
- A versão do SDK. Os dois primeiros números (
10.0) dizem a versão do .NET. O terceiro (112) tem duas partes: o1é a "faixa" de recursos do SDK e o12é a 12.ª correção. A aula Versões do C# e do .NET explica a numeração. - Microsoft.NETCore.App 10.0.12
- O Runtime básico, versão
10.0.12: tudo o que um programa de terminal precisa. É o que este guia usa. - Microsoft.AspNetCore.App 10.0.12
- Um runtime extra, para sites e serviços na internet (ASP.NET Core). O SDK do Ubuntu o instala junto.
- [/usr/lib/dotnet/…]
- A pasta onde cada um está. No Ubuntu, o .NET mora em
/usr/lib/dotnet.
Abrindo o .NET da Ana
Vamos olhar a pasta do .NET por dentro. O ls lista o que há nela, e o du -sh mostra o tamanho:
$ ls /usr/lib/dotnet dnx dotnet « o comando dotnet host library-packs LICENSE.txt metadata packs sdk « o SDK: compilador, MSBuild, comandos sdk-manifests shared « os Runtimes templates « os modelos do dotnet new ThirdPartyNotices.txt $ du -sh /usr/lib/dotnet 545M /usr/lib/dotnet $ du -sh /usr/lib/dotnet/sdk; du -sh /usr/lib/dotnet/shared; du -sh /usr/lib/dotnet/packs 340M /usr/lib/dotnet/sdk 96M /usr/lib/dotnet/shared 98M /usr/lib/dotnet/packs
O .NET inteiro ocupa 545 MB, e a maior parte (340 MB) é o SDK: as ferramentas de quem programa. Os Runtimes, que é o que um programa precisa para rodar, ficam em shared, com menos de 100 MB. A pasta packs guarda as "plantas" da biblioteca que o compilador consulta para saber quais classes existem.
O compilador e o MSBuild, dentro do SDK
$ ls /usr/lib/dotnet/sdk/10.0.112 | grep -i -E "^(MSBuild.dll|dotnet.dll|Roslyn)$" dotnet.dll « os comandos run, new, build… MSBuild.dll « o "mestre de obras" do build Roslyn « a pasta do compilador de C# $ ls /usr/lib/dotnet/sdk/10.0.112/Roslyn/bincore | head cs csc « csc = C Sharp Compiler csc.deps.json csc.dll csc.runtimeconfig.json de es fr it ja
O compilador de C# se chama csc (C Sharp Compiler), e o projeto que o criou se chama Roslyn. Repare num detalhe curioso: o csc.dll também é um programa .NET, escrito em C#. O compilador de C# é escrito em C#. As pastas cs, de, es, fr… guardam as mensagens de erro traduzidas (cs, aqui, é tcheco). É de uma pasta dessas, a pt-BR, que vêm as mensagens em português que você vê no terminal da Ana. Você nunca precisa chamar o csc diretamente: o dotnet run e o MSBuild fazem isso por você.
O Runtime e a biblioteca de classes
$ cd /usr/lib/dotnet/shared/Microsoft.NETCore.App/10.0.12 $ ls *.dll | wc -l 172 « 172 bibliotecas prontas $ du -h System.Console.dll System.Private.CoreLib.dll libcoreclr.so libclrjit.so 184K System.Console.dll « onde mora o Console 14M System.Private.CoreLib.dll « o coração da biblioteca: int, string, Math… 6,9M libcoreclr.so « o CLR, o motor 3,2M libclrjit.so « o JIT, o tradutor de última hora
Aqui está a "despensa" do restaurante: 172 arquivos .dll, cada um com uma parte da biblioteca de classes. Quando você escreve Console.WriteLine, o código do WriteLine vem do System.Console.dll; ele não fica dentro do seu programa. Os arquivos .so são programas do Linux de verdade, em código de máquina: o libcoreclr.so é o CLR e o libclrjit.so é o JIT.
Um programa consegue perguntar ao .NET quem ele é. Rode e compare com o terminal da Ana:
Experimente: rode e veja a versão do .NET, o sistema e o processador. Aqui no editor aparecem Sistema: Browser e Processador: Wasm, diferentes da saída da Ana logo abaixo. Não é erro: o programa mostra o .NET e o computador onde ele está rodando, e aqui ele roda dentro do seu navegador (em WebAssembly), não no Ubuntu da Ana. O System.Console é o mesmo nos dois.
using System.Runtime.InteropServices;
Console.WriteLine($".NET: {RuntimeInformation.FrameworkDescription}");
Console.WriteLine($"Sistema: {RuntimeInformation.OSDescription}");
Console.WriteLine($"Processador: {RuntimeInformation.ProcessArchitecture}");
Console.WriteLine($"O Console vem de: {typeof(Console).Assembly.GetName().Name}");
$ dotnet run info.cs .NET: .NET 10.0.12 « o Runtime, não o SDK Sistema: Ubuntu 26.04.1 LTS Processador: X64 « Intel/AMD de 64 bits O Console vem de: System.Console « o System.Console.dll da despensa
Não se preocupe com o using nem com o typeof: eles aparecem nas aulas Namespaces e using e Reflexão. O importante aqui é que o programa mostrou .NET 10.0.12, a versão do Runtime: quem roda o programa é o Runtime; o SDK só ajudou a construí-lo.
Do .cs ao programa: o caminho completo
Quando a Ana digita dotnet run ola.cs, acontecem estas etapas, nesta ordem:
- O SDK prepara o build. O MSBuild descobre o que precisa ser compilado e com quais bibliotecas.
- O Roslyn compila. Ele lê o
ola.cs, confere tudo (tipos, nomes, ponto e vírgula) e, se não houver erro, escreve a IL num arquivoola.dll. Se houver erro, para aqui, e nada roda. - O CLR carrega o programa. Ele abre o
ola.dlle as bibliotecas que ele usa (como oSystem.Console.dll). - O JIT traduz. Na primeira vez que cada método é chamado, o JIT transforma a IL dele em instruções do processador (x64, no computador da Ana) e guarda o resultado na memória.
- O processador executa essas instruções, e o texto aparece na tela.
O dotnet run esconde os arquivos que cria. O comando dotnet build faz só as etapas 1 e 2, e diz onde guardou o resultado:
$ dotnet build ola.cs Determinando os projetos a serem restaurados... Todos os projetos estão atualizados para restauração. ola -> /home/ana/.local/share/dotnet/runfile/ola-d3e0b993ea942ae2aa43a2c132f9667a87cb5c1410a99c454aae33ed39b33823/bin/debug/ola.dll
O ola.dll foi parar numa pasta escondida, dentro de ~/.local/share/dotnet/runfile, com um nome comprido (o nome do arquivo mais um código que identifica a pasta onde ele está). Vamos entrar nela:
$ cd ~/.local/share/dotnet/runfile/ola-*/bin/debug $ ls -l total 108 -rwxr-xr-x 1 ana ana 78904 out 17 12:37 ola « um "lançador" para Linux -rw-rw-r-- 1 ana ana 381 out 17 12:37 ola.deps.json « a lista de bibliotecas usadas -rw-rw-r-- 1 ana ana 4608 out 17 12:37 ola.dll « o seu programa, em IL -rw-rw-r-- 1 ana ana 10872 out 17 12:37 ola.pdb « informações para depurar -rw-rw-r-- 1 ana ana 2000 out 17 12:37 ola.runtimeconfig.json « qual Runtime usar
| Arquivo | O que é |
|---|---|
ola.dll | O programa de verdade: a IL que o Roslyn gerou, mais a descrição de tudo o que há nele (os "metadados"). Só 4608 bytes, porque o Console e o resto da biblioteca ficam no Runtime. O nome .dll (dynamic-link library) vem do Windows e é usado em todos os sistemas. |
ola | O apphost, um lançador: um programa pequeno do Linux que acha o Runtime e manda ele rodar o ola.dll. No Windows, ele se chama ola.exe. |
ola.runtimeconfig.json | Um bilhete para o lançador: "este programa precisa do Microsoft.NETCore.App, versão 10.0 ou mais nova". |
ola.deps.json | A lista de bibliotecas extras de que o programa depende (aqui, nenhuma). |
ola.pdb | O "mapa" que liga cada pedaço da IL à linha do ola.cs. É por causa dele que uma exceção diz line 2 (aula Depuração). |
O comando file do Linux diz que tipo de arquivo cada um é:
$ file ola ola.dll ola: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=622d7093dbcd55b2ef4ff850254d90f54a4213c7, stripped ola.dll: PE32 executable for MS Windows 4.00 (console), Intel i386 Mono/.Net assembly, 3 sections $ head -c 2 ola.dll; echo MZ « a assinatura dos programas do Windows
O ola é um programa do Linux (ELF, para processador x86-64). Já o ola.dll o file chama de "executável do Windows", com a etiqueta Mono/.Net assembly: ele usa o mesmo formato de arquivo dos programas do Windows (que começam com as letras MZ, as iniciais de um engenheiro da Microsoft dos anos 1980), mas por dentro não tem instruções de processador nenhum, só IL. Por isso o mesmo ola.dll roda em qualquer sistema. Um arquivo assim, com IL e metadados, se chama assembly no mundo .NET.
Dá para rodar o programa pronto de dois jeitos, sem compilar de novo:
$ ./ola « pelo lançador Olá, mundo! $ dotnet ola.dll « entregando o .dll direto ao dotnet Olá, mundo!
Por dentro: a IL e o JIT
Vamos seguir um método pequeno do código-fonte até o processador. Este programa tem um método Somar, que soma dois números (os métodos têm aula própria, Métodos; por enquanto, leia Somar(2, 3) como "some 2 e 3"):
Console.WriteLine(Conta.Somar(2, 3));
static class Conta
{
public static int Somar(int a, int b) => a + b;
}
$ dotnet run soma.cs 5
1. O que o Roslyn escreveu: a IL
Dentro do soma.dll, o método Somar virou só quatro bytes de IL: 02 03 58 2A (lidos com um programa de reflexão, assunto da aula Reflexão). Cada byte é uma instrução da "língua universal":
| Byte | Instrução de IL | O que faz |
|---|---|---|
02 | ldarg.0 | "Pegue o argumento 0" (o a) e ponha numa pilha de trabalho |
03 | ldarg.1 | "Pegue o argumento 1" (o b) e ponha na pilha |
58 | add | Tire os dois de cima da pilha, some e ponha o resultado de volta |
2A | ret | Devolva o que está na pilha |
Repare que a IL não fala de nenhum processador: ela não sabe se vai rodar num Intel, num ARM do celular ou num Mac. É o "passo a passo universal" da receita.
2. O que o JIT fez: código de máquina
O .NET tem uma chave de diagnóstico, a variável DOTNET_JitDisasm, que pede ao JIT para mostrar o que ele gerou para um método. A Ana pediu o Somar (o -c Release pede a versão "de entrega", sem os extras de depuração, para a listagem ficar menor):
$ DOTNET_JitDisasm=Somar dotnet run soma.cs -c Release
; Assembly listing for method Conta:Somar(int,int):int (Tier0)
; Emitting BLENDED_CODE for generic X64 + VEX on Unix
; Tier0 code
; rbp based frame
; partially interruptible
; compiling with minopt
G_M000_IG01: ;; offset=0x0000
push rbp
sub rsp, 16
lea rbp, [rsp+0x10]
mov dword ptr [rbp-0x04], edi « guarda o a
mov dword ptr [rbp-0x08], esi « guarda o b
G_M000_IG02: ;; offset=0x0010
mov eax, dword ptr [rbp-0x04] « pega o a
add eax, dword ptr [rbp-0x08] « soma o b: aqui está o a + b
G_M000_IG03: ;; offset=0x0016
add rsp, 16
pop rbp
ret « devolve o resultado
; Total bytes of code 28
5 « só agora o Somar roda e o resultado aparece
Isso é código de máquina x64 de verdade, escrito na forma legível (assembly): as instruções que o processador Intel/AMD da Ana executou. Os 4 bytes de IL viraram 28 bytes de instruções do processador. Você não precisa entender cada linha; repare só no add, que é o a + b do seu código, e em três detalhes da primeira parte:
Tier0: "nível 0". Na primeira vez, o JIT traduz rápido, sem caprichar, para o programa começar logo. Se o método for chamado muitas vezes, o .NET o traduz de novo, agora caprichando (o "nível 1"). Isso se chama compilação em camadas.X64eon Unix: o JIT gerou código para o processador e o sistema desta máquina. No Mac com chip M, a mesma IL viraria código ARM64.- A listagem aparece antes do
5: o JIT traduz oSomarna primeira vez que ele é chamado, um instante antes de rodar. Só depois a conta é feita e o5chega à tela.
Missão: use o mesmo Somar para mostrar a soma de 10 e 20. Mude só os números da primeira linha e rode: a saída deve ser 30.
Console.WriteLine(Conta.Somar(2, 3));
static class Conta
{
public static int Somar(int a, int b) => a + b;
}
Console.WriteLine(Conta.Somar(10, 20));
static class Conta
{
public static int Somar(int a, int b) => a + b;
}
Enquanto o programa roda, ele cria textos, listas e objetos na memória. O CLR acompanha tudo isso e, de tempos em tempos, o coletor de lixo passa recolhendo o que ninguém usa mais, para a memória não acabar. Você não precisa fazer nada; é por isso que o C# é chamado de linguagem gerenciada. A aula Memória e Coletor de Lixo mostra o coletor trabalhando.
Muitos nomes, um .NET só
O .NET mudou de nome algumas vezes, e a internet está cheia de material de todas as épocas. Este é o mapa:
| Nome | Época | Roda em | Situação hoje |
|---|---|---|---|
| .NET Framework (1.0 a 4.8.1) | 2002 em diante | Só Windows | Ainda vem no Windows e roda muito programa antigo, mas não ganha novidades. Fica parado no C# 7.3. |
| Mono | 2004 em diante | Linux, macOS, Android, iPhone | A versão livre que levou o C# para fora do Windows. Ainda vive dentro do Unity e de partes do .NET para celular. |
| .NET Core (1.0 a 3.1) | 2016 a 2019 | Linux, Windows, macOS | O .NET novo, livre e multiplataforma. Todas as versões já saíram de suporte. |
| .NET (5, 6, 7, 8, 9, 10…) | 2020 em diante | Linux, Windows, macOS | A continuação do .NET Core, sem o "Core" no nome (o 4 foi pulado para não confundir com o .NET Framework 4). É este que o guia usa: o .NET 10. |
Qual usar? Para programas novos, sempre o .NET atual (hoje, o .NET 10). O .NET Framework só faz sentido para manter um programa antigo do Windows que já usa ele. Quando um tutorial disser "crie um projeto .NET Framework", ou mostrar um caminho como C:\Windows\Microsoft.NET\Framework, ele é dessa época antiga.
Quem faz o seu .NET
O código do .NET é aberto, então outras empresas podem compilá-lo. O .NET da Ana não foi baixado do site da Microsoft: foi a Canonical, a empresa do Ubuntu, que o compilou a partir do código-fonte e o colocou no repositório do Ubuntu. Por isso as versões são um pouco diferentes: no mesmo mês, o site da Microsoft tinha o SDK 10.0.402 com o Runtime 10.0.13, e o Ubuntu, o SDK 10.0.112 com o Runtime 10.0.12. Os dois são o mesmo .NET 10 e o mesmo C# 14; a aula Versões explica os números e a aula Instalar no Linux mostra as duas formas de instalar.
Quando dá errado
No .NET SDKs were found.
Para ver o que acontece num computador que só tem o Runtime, a Ana copiou só as peças do Runtime para uma pasta ~/rt e tentou usar o dotnet de lá:
$ ls ~/rt ~/rt/shared
/home/ana/rt:
dotnet
host
shared
/home/ana/rt/shared:
Microsoft.NETCore.App « só o Runtime; nada de sdk
$ ~/rt/dotnet run ola.cs
The command could not be loaded, possibly because:
* You intended to execute a .NET application:
The application 'run' does not exist or is not a managed .dll or .exe.
* You intended to execute a .NET SDK command:
No .NET SDKs were found.
Download a .NET SDK:
https://aka.ms/dotnet/download
Learn about SDK resolution:
https://aka.ms/dotnet/sdk-not-found
$ echo $?
155
O que significa: esta mensagem sai em inglês, porque vem do "anfitrião" do .NET, a parte mais básica, que não tem tradução. Ela diz: "não consegui carregar o comando, talvez porque você quis rodar um aplicativo chamado run (que não existe) ou um comando do SDK, mas nenhum SDK foi encontrado". O Runtime sabe rodar programas prontos (o ~/rt/dotnet ola.dll funciona), mas o run, o build e o new moram no SDK.
Como consertar: instale o SDK, e não só o Runtime: no Ubuntu, sudo apt install dotnet-sdk-10.0 (aula Instalar no Linux).
You must install or update .NET to run this application.
A Ana editou o ola.runtimeconfig.json de uma cópia do programa para dizer que ele precisa do .NET 11, que ela não tem, e tentou rodar:
$ grep version ~/ola-pronto/ola.runtimeconfig.json
"version": "11.0.0"
$ dotnet ~/ola-pronto/ola.dll
You must install or update .NET to run this application.
App: /home/ana/ola-pronto/ola.dll
Architecture: x64
Framework: 'Microsoft.NETCore.App', version '11.0.0' (x64) « o que o programa pede
.NET location: /usr/lib/dotnet/
The following frameworks were found:
10.0.12 at [/usr/lib/dotnet/shared/Microsoft.NETCore.App] « o que a Ana tem
Learn more:
https://aka.ms/dotnet/app-launch-failed
To install missing framework, download:
https://aka.ms/dotnet-core-applaunch?framework=Microsoft.NETCore.App&framework_version=11.0.0&arch=x64&rid=ubuntu.26.04-x64&os=ubuntu.26.04
$ echo $?
150
O que significa: "você precisa instalar ou atualizar o .NET para rodar este aplicativo". O programa pede o Runtime 11.0, e só existe o 10.0.12. Um programa feito para uma versão roda nas correções mais novas da mesma versão (um programa do 10.0.0 roda no 10.0.12), mas não "desce" para uma versão mais velha. Isso acontece de verdade quando alguém manda um programa compilado para um .NET mais novo que o seu.
Como consertar: instale o Runtime que a mensagem pede (o endereço do fim já leva à página certa) ou peça um programa compilado para a sua versão.
O que acontece: no Windows, sites antigos e alguns programas pedem o ".NET Framework 4.8". Ele não serve para este guia: não tem o comando dotnet nem o C# 14. No Linux e no macOS, ele nem existe.
Como consertar: instale o .NET SDK 10 (aula Instalar no Windows e macOS). Os dois podem ficar instalados juntos no Windows sem problema.
Referência
| Termo | O que é |
|---|---|
| .NET | A plataforma: compilador, Runtime, biblioteca e ferramentas |
| SDK | O kit de quem programa: tudo do Runtime + compilador + comandos dotnet run/new/build |
| Runtime | O necessário para rodar programas prontos: CLR, JIT, coletor de lixo e biblioteca |
Roslyn (csc) | O compilador de C#: transforma .cs em IL |
| MSBuild | Organiza o build: decide o que compilar, com quais opções e bibliotecas |
| IL | A linguagem intermediária que fica dentro dos .dll |
| Assembly | Um arquivo .dll (ou .exe) com IL e metadados |
| CLR | O motor que carrega e roda os assemblies (libcoreclr.so) |
| JIT | Traduz IL para código de máquina enquanto o programa roda (libclrjit.so) |
| BCL (biblioteca de classes) | As classes prontas: Console, Math, List, File… |
| GC (coletor de lixo) | Recolhe a memória que o programa não usa mais |
| Comando | Para quê |
|---|---|
dotnet --list-sdks | Lista os SDKs instalados |
dotnet --list-runtimes | Lista os Runtimes instalados |
dotnet --version | Mostra a versão do SDK em uso |
dotnet build ola.cs | Compila sem rodar e diz onde ficou o .dll |
dotnet arquivo.dll | Roda um programa pronto (só precisa do Runtime) |
Exercícios
1. A linguagem intermediária
Qual é a sigla da linguagem intermediária que o compilador escreve dentro do .dll?
2. Listar os Runtimes
Complete o comando que mostra os Runtimes instalados:
3. O pacote certo
Complete o nome do pacote do Ubuntu que tem tudo o que o guia precisa (o kit de quem programa):
4. Quem transforma a IL em instruções do processador, enquanto o programa roda?
5. Um colega só quer rodar o programa que a Ana fez, sem programar. O que ele precisa instalar, no mínimo?
6. Por que o mesmo ola.dll roda no Linux, no Windows e no Mac?
7. O dotnet run ola.cs respondeu No .NET SDKs were found. O que falta?
Missão final: o caminho do código
Missão: o programa mostra as etapas do caminho do código, mas a Ana trocou a ordem. Ponha as três linhas na ordem certa (Roslyn, CLR, JIT) e rode.
Console.WriteLine("3. JIT: IL vira código de máquina");
Console.WriteLine("1. Roslyn: .cs vira IL");
Console.WriteLine("2. CLR: carrega o .dll");
Console.WriteLine("1. Roslyn: .cs vira IL");
Console.WriteLine("2. CLR: carrega o .dll");
Console.WriteLine("3. JIT: IL vira código de máquina");
Resumo
- O .NET é a plataforma por baixo do C#. O SDK é para quem programa (compilador e comandos); o Runtime é para quem só roda programas. O SDK já traz o Runtime.
- O caminho: o Roslyn compila o
.cspara IL num.dll; o CLR carrega o.dll; o JIT traduz a IL para o processador na hora de rodar. - O
Consolee as outras classes prontas vêm da biblioteca de classes, nos 172.dlldo Runtime. O coletor de lixo cuida da memória. dotnet --list-sdksedotnet --list-runtimesmostram o que está instalado. No Ubuntu, tudo fica em/usr/lib/dotnet.- .NET Framework (só Windows, antigo), Mono, .NET Core e .NET 5 a 10 são a mesma família; o guia usa o .NET 10.
- Próximo passo: entender os números das versões, em Versões do C# e do .NET.