Article image
Joao Morais
Joao Morais28/08/2026 23:53
Compartilhe

Migrando pro .NET em 2026: o que eu aprendi no módulo de Fundamentos

    Parte 1 de uma série que eu vou escrever conforme avanço na trilha .NET da DIO.

    De onde eu venho

    Meu dia a dia é PHP/Laravel, JavaScript, React e Next.js. .NET nunca fez parte disso. O mais perto que cheguei do C# foram uns projetinhos de jogo que nunca saíram da minha máquina.

    Esse ano eu decidi entrar no ecossistema pra valer, porque quero tentar vagas .NET ainda em 2026. Comecei pela trilha da DIO, e resolvi escrever um artigo por módulo — tanto pra fixar o que estudei quanto pra registrar as coisas que confundem quem chega de fora. Boa parte do que eu tropecei nesse primeiro módulo não tinha nada a ver com programar. Era o ecossistema em volta.

    A primeira coisa que me travou foi o nome

    Eu não fazia ideia do que era ".NET Framework". Pesquisando qualquer erro você acha resposta pra ".NET Framework", pra ".NET Core" e pra ".NET", e por muito tempo eu achei que fossem apelidos da mesma coisa. Não são.

    • .NET Framework — o original, de 2002. Roda só no Windows. Parou na versão 4.8: ainda recebe correção de segurança, mas não ganha mais nada novo.
    • .NET Core — reescrito praticamente do zero, com o objetivo de ser multiplataforma. Foi da versão 1.0 até a 3.1.
    • .NET (sem sobrenome) — depois do Core 3.1, a Microsoft pulou a versão 4.0 de propósito, pra ninguém confundir com o Framework 4.x, e foi direto pro 5.0. Junto, tirou a palavra "Core" do nome. De 2020 pra cá é só ".NET" mesmo.

    O que destravou a minha cabeça foi entender que .NET Framework 4.8 e .NET 8 não são a mesma linha. São dois produtos diferentes: um congelado, outro vivo. Quando você acha uma resposta antiga no Stack Overflow, a primeira pergunta é "isso é de qual dos dois?".

    E sim, eu achava que .NET era coisa só de Windows. Era verdade até 2016. Hoje roda em Linux, macOS e container sem gambiarra nenhuma.

    O curso ensina .NET 6 e nós estamos em 2026

    Isso me incomodou, então fui atrás.

    O .NET 6 saiu de suporte em 12 de novembro de 2024. Ou seja, o material do curso usa uma versão que a Microsoft já não mantém há quase dois anos.

    Como está o cenário hoje, agosto de 2026:

    Versão Situação .NET 6 Fora de suporte desde nov/2024 .NET 8 e 9 Suporte acaba em 10/11/2026 .NET 10 LTS — é o que eu instalei pra estudar .NET 11 Em preview (Preview 6 saiu em julho). GA marcado pra 10/11/2026, e é STS A lógica das versões, que também não era óbvia pra mim: sai uma por ano, em novembro. Versão par é LTS (3 anos de suporte), ímpar é STS (18 meses). Por isso o 10 é a escolha segura agora e o 11 vai ser uma versão de ciclo curto.

    Na prática, isso muda pouco pra quem está no módulo de fundamentos — if, for, List, tipos, nada disso mudou. Eu instalei o .NET 10 e fiz o curso inteiro nele sem problema. Mas se você é de outra stack, vale saber disso antes de sair copiando tutorial de 2021.

    Por que o meu Program.cs não tem Main

    Essa foi a diferença que mais me confundiu na prática. Todo tutorial antigo mostra isso:

    namespace MinhaApp
    {
      class Program
      {
          static void Main(string[] args)
          {
              Console.WriteLine("Hello, World!");
          }
      }
    }
    

    E o arquivo do projeto do curso começa assim, código solto, sem classe e sem Main:

    using DesafioFundamentos.Models;
    
    Console.OutputEncoding = System.Text.Encoding.UTF8;
    
    decimal precoInicial = 0;
    

    As duas formas são válidas. A segunda se chama top-level statements e virou o padrão dos templates a partir do .NET 6 — o compilador gera o Main por baixo dos panos pra você. Junto com isso vem o implicit usings: repare que a classe Estacionamento usa List<string> e .Any() sem nenhum using System.Collections.Generic ou using System.Linq no topo do arquivo. O SDK injeta os using mais comuns automaticamente.

    Sabendo disso, para de parecer que o projeto está quebrado ou incompleto.

    As ferramentas

    Estou usando o Visual Studio 2026, e a primeira coisa que aprendi é que ele não é o VS Code. Vindo de PhpStorm e VS Code, o Visual Studio é uma IDE completa e bem mais pesada — ele resolve muita coisa pra você (o gerenciamento de projeto e solução, o build, o debugger) e em troca esconde o que está acontecendo. As alternativas são VS Code com a extensão C# Dev Kit, ou o Rider.

    Fui atrás do CLI justamente por causa disso, pra ver o processo por baixo:

    dotnet new console -n MeuApp   # cria o projeto
    dotnet build                     # compila
    dotnet run                       # compila e executa
    

    E aqui está a mudança de ritmo real vindo de linguagem interpretada: existe um passo de compilação. Em PHP ou JS eu salvo e recarrego. Aqui, todo código alterado precisa ser compilado antes de rodar. Parece bobagem escrita assim, mas muda o jeito de trabalhar — e é o que dá ao C# o erro em tempo de compilação, que pega besteira antes do programa existir.

    Sintaxe: o que realmente é diferente

    A maior parte da sintaxe é familiar pra quem já programa. O que exigiu ajuste foi:

    Tipagem estática de verdade. Declarou int, é int. Não tem conversão silenciosa como o PHP faz. Existe o var, mas ele é inferência em tempo de compilação, não é tipo dinâmico — depois de definido, não muda.

    Odecimal pra dinheiro. Essa é a que mais vale a pena levar. Valor monetário em C# usa decimal, não double nem float. Os dois últimos são ponto flutuante binário e não conseguem representar 0,1 exatamente — em cálculo de dinheiro, isso vira centavo errado depois de algumas operações. O decimal é decimal de verdade, mais lento e com menos alcance, mas exato pro que importa aqui.

    Coleções genéricas. List<string> é uma lista que só aceita string, garantido pelo compilador. Depois de anos com array de PHP aceitando qualquer coisa misturada, é uma restrição que dá alívio.

    Interpolação de string com $"texto {variavel}", praticamente igual ao template literal do JS.

    O projeto do módulo: sistema de estacionamento

    O desafio final é um sistema de console: cadastrar veículo pela placa, remover cobrando precoInicial + precoPorHora * horas, e listar. A DIO entrega o repositório pela metade, marcado com TODO, e você completa.

    Implementei e funcionou. E foi revisando depois que eu esbarrei no aprendizado que mais me marcou do módulo — sobre igualdade em C#.

    O método de remoção fica assim:

    if (veiculos.Any(x => x.ToUpper() == placa.ToUpper()))   // busca ignorando maiúsculas
    {
      // ...
      veiculos.Remove(placa);                              // remove comparando exato
    }
    

    As duas linhas usam regras diferentes. Se a placa entra como abc1234 e alguém digita ABC1234 pra dar saída: o Any normaliza os dois lados e encontra, o valor é calculado, e o Remove procura a string exata "ABC1234", não acha, e não remove nada. O programa ainda imprime "foi removido".

    O motivo é que List<T>.Remove não aceita a sua regra de comparação — ele usa o comparador padrão do tipo, e pra string isso é ordinal, byte a byte, sensível a maiúsculas. Vindo do PHP, onde eu resolvo isso com array_search e escolho a comparação, essa distinção não me passou pela cabeça. E o Remove devolve um bool dizendo se removeu — que eu simplesmente ignorei.

    Como ficou depois:

    // uma única definição de "é o mesmo veículo"
    string veiculoEncontrado = veiculos
      .FirstOrDefault(x => x.Equals(placa, StringComparison.OrdinalIgnoreCase));
    
    if (veiculoEncontrado is null)
    {
      Console.WriteLine("Desculpe, esse veículo não está estacionado aqui.");
      return;
    }
    
    if (!int.TryParse(Console.ReadLine(), out int horas) || horas < 0)
    {
      Console.WriteLine("Quantidade de horas inválida.");
      return;
    }
    
    decimal valorTotal = precoInicial + precoPorHora * horas;
    veiculos.Remove(veiculoEncontrado);   // remove o item que está de fato na lista
    

    Três coisas que eu levo daqui:

    • Guarde o item encontrado, não a chave digitada. Se você buscou por uma regra, aja sobre o resultado da busca.
    • StringComparison.OrdinalIgnoreCase no lugar de ToUpper(). Não cria strings novas a cada comparação e não depende da cultura do sistema.
    • int.TryParse no lugar de int.Parse. Com Parse, o usuário digitar "duas" derruba o programa com exceção. TryParse devolve false e você trata.

    Então, dá pra migrar pro .NET em 2026?

    É a pergunta que eu estou respondendo na prática, então vou ser honesto sobre onde eu estou.

    O que eu percebi até aqui é que o módulo de fundamentos é rápido pra quem já programa. Lógica, laço, coleção, orientação a objetos — é vocabulário novo pra ideia velha. O que consome tempo de verdade é o ecossistema: entender versão, SDK, NuGet, o modelo de compilação, o jeito da IDE.

    E o que eu não aprendi nesse módulo, que é justamente o que as vagas pedem: ASP.NET Core, Entity Framework, SQL Server. Terminar Fundamentos não faz de ninguém um dev .NET, e não é isso que eu vou dizer numa entrevista. Faz de mim alguém que consegue ler e escrever C# com segurança — que é o pré-requisito pra tudo que vem depois.

    A parte que me deixa otimista é bem concreta: no mercado daqui, .NET aparece muito em empresa consolidada, saúde, governo e financeiro. É um ecossistema com vaga sobrando e menos gente nova entrando do que no lado JS. Se você já tem estrada em outra stack, o custo de entrada é menor do que parece de fora — e o que atrapalha no começo é mais confusão de nomenclatura do que dificuldade técnica.

    Código do desafio: https://github.com/jpmedeirosmorais/trilha-net-fundamentos-desafio

    Compartilhe
    Comentários (0)