O primeiro programa clássico imprime uma linha de texto. Em C# ele fica assim:
Saída:
Hello, World!
Linha por linha
using System;permite escreverConsoleem vez do nome completoSystem.Console.Consoleé uma classe do namespaceSystem(veja namespaces e using).class Programdeclara uma classe. Todo código C# fica dentro de um tipo; o nomeProgramé uma convenção, não uma exigência.static void Main()é o ponto de entrada. Quando o programa começa, o runtime procura um método static chamadoMaine o chama.staticsignifica que ele pertence à própria classe, então nenhum objeto precisa ser criado antes.voidsignifica que ele não retorna nada.Console.WriteLine("Hello, World!");chama o métodoWriteLinecom um argumento string. Toda instrução termina com ponto e vírgula.- As chaves
{ }marcam o corpo da classe e do método.
C# diferencia maiúsculas de minúsculas. console.writeline e main são nomes diferentes de Console.WriteLine e Main, e nenhum dos dois existe.
Console.WriteLine vs Console.Write
WriteLine adiciona uma quebra de linha depois do texto. Write não, então a próxima saída continua na mesma linha. Os dois aceitam qualquer tipo, não só strings: números, booleanos e objetos são convertidos com o método ToString() deles.
Saída:
Loading.. done
42
True
Item: coffee
coffee costs 3.20
coffee costs 3.20
Repare que true é impresso como True: é o que bool.ToString() retorna. A forma $"...", chamada interpolação de strings, é a que você mais vai usar; veja interpolação de strings para os códigos de formato como :F2.
Lendo a entrada com Console.ReadLine
Console.ReadLine() espera o usuário digitar uma linha e apertar Enter, e então retorna essa linha como string, sem a quebra de linha. No fim da entrada (por exemplo, quando a entrada é redirecionada de um arquivo que acabou) ele retorna null.
Saída:
What is your name? How old are you?
Hi Maya, next year you will be 28.
Quando você executa isto em um terminal, o texto que você digita aparece depois de cada pergunta. A saída acima não tem texto digitado porque a entrada foi redirecionada (passada por pipe) em vez de digitada, então só aparece o que o próprio programa escreve.
ReadLine sempre retorna texto. Para usar o valor como número, você precisa convertê-lo. int.Parse(text) lança uma FormatException quando o texto não é um número; int.TryParse retorna false no lugar, e é por isso que é a escolha certa para entradas do usuário. Os detalhes estão em conversão de tipos.
Dois métodos relacionados: Console.Read() retorna o próximo caractere como um código int, e Console.ReadKey() lê uma única tecla sem esperar o Enter (só funciona em um terminal interativo).
As outras formas do método Main
Main pode receber os argumentos da linha de comando e pode retornar um código de saída. Todos estes são pontos de entrada válidos:
static void Main()
static void Main(string[] args)
static int Main()
static int Main(string[] args)
static async Task Main() // C# 7.1 and later
static async Task<int> Main(string[] args) // C# 7.1 and later
Um int retornado vira o código de saída do processo, que scripts e sistemas de CI leem para decidir se o programa teve sucesso (0 significa sucesso por convenção).
Saída:
Got 0 argument(s)
Execute com dotnet run -- apples pears e args terá "apples" e "pears". O -- separa os argumentos do seu programa dos argumentos da ferramenta dotnet.
Comentários
C# tem três tipos de comentário. O compilador ignora todos eles.
// A single-line comment runs to the end of the line.
/* A block comment
can span several lines. */
/// <summary>
/// An XML documentation comment. Editors show it as the tooltip for the method.
/// </summary>
static decimal ApplyDiscount(decimal price) => price * 0.9m;
Use // para anotações dentro do código. Comentários /// ficam em tipos e membros públicos; a IDE os mostra quando você passa o mouse sobre uma chamada, e o compilador pode exportá-los para um arquivo XML usado por ferramentas de documentação.
Criando e executando um projeto com dotnet
Na sua própria máquina, instale o .NET SDK a partir de dotnet.microsoft.com e depois:
dotnet new console -o HelloApp
cd HelloApp
dotnet run
Hello, World!
dotnet new console cria dois arquivos: HelloApp.csproj (o arquivo de projeto: framework de destino, configurações, referências a pacotes) e Program.cs. dotnet run compila o projeto e o executa. dotnet build compila sem executar e grava a saída em bin/Debug/net8.0/ (o nome da pasta segue o seu framework de destino).
Instruções de nível superior (C# 9 em diante)
Abra o Program.cs gerado e você vai encontrar isto, e nada mais:
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
Este é um programa com instruções de nível superior (top-level statements), um recurso do C# 9. O compilador gera a classe Program e o método Main em volta das suas instruções. O using System; também não aparece porque projetos do .NET 6 em diante habilitam os implicit usings: namespaces comuns como System, System.IO, System.Linq e System.Collections.Generic são importados para o projeto inteiro.
Programas de nível superior ainda podem ler args, usar await e fazer return de um código de saída:
// C# 9 and later: the whole Program.cs
Console.Write("Name: ");
string? name = Console.ReadLine();
Console.WriteLine($"Hello, {name}! You passed {args.Length} arguments.");
return 0;
Só um arquivo por projeto pode conter instruções de nível superior, e os tipos (classes, records) precisam vir depois delas. A anotação string? é um tipo de referência anulável (C# 8), e está ali porque ReadLine pode retornar null. A forma explícita com class Program usada nos exemplos desta página é equivalente e é o que você vai ver em código mais antigo e na maioria dos scripts Unity, então vale saber ler as duas. Passe --use-program-main para dotnet new console se preferir a forma explícita em projetos novos.
Os primeiros erros que você vai ver
- CS1002: ; expected. Falta o ponto e vírgula de uma instrução. O erro é informado no fim da linha em que ele falta.
- CS0103: The name 'console' does not exist in the current context. Maiúsculas e minúsculas erradas, ou falta um
using System;em um projeto sem implicit usings. - CS5001: Program does not contain a static 'Main' method suitable for an entry point.
Mainestá escrito errado, não éstaticou tem uma assinatura não suportada. - CS0017: Program has more than one entry point defined. Duas classes têm um
Maincada. Mantenha uma, ou escolha uma com a configuraçãoStartupObjectno.csproj. - A janela fecha imediatamente. Quando um app de console é iniciado com um duplo clique, a janela fecha quando o
Mainretorna. Execute-o a partir de um terminal, ou adicioneConsole.ReadKey();no fim enquanto testa.
Perguntas frequentes
Como escrever Hello World em C#?
Coloque Console.WriteLine("Hello, World!"); dentro de um método static void Main() de uma classe, com using System; no topo. Em um projeto criado com dotnet new console no .NET 6 ou posterior, o arquivo inteiro pode ser só essa linha, porque as instruções de nível superior geram a classe e o Main para você.
O que é o método Main em C#?
Main é o ponto de entrada: o método que o runtime chama quando o programa começa. Ele precisa ser static, pode retornar void ou int (o código de saída) e pode receber um parâmetro string[] args com os argumentos da linha de comando. Um programa precisa de exatamente um.
Qual a diferença entre Console.Write e Console.WriteLine?
Console.WriteLine escreve o texto seguido de uma quebra de linha, então a próxima saída começa em uma linha nova. Console.Write escreve só o texto, então a próxima saída continua na mesma linha. Console.WriteLine() sem argumentos imprime uma linha vazia.
Como ler a entrada do usuário em C#?
Console.ReadLine() lê uma linha de texto e a retorna como string (sem a quebra de linha), ou null quando não há mais entrada. Para obter um número, converta a string: int.TryParse(Console.ReadLine(), out int n) retorna false em vez de quebrar quando o texto não é um número.
Como executar um programa C# pela linha de comando?
Instale o .NET SDK e execute dotnet new console -o HelloApp para criar um projeto, cd HelloApp, e dotnet run para compilar e executar. dotnet build só compila e coloca a saída em bin/Debug/net8.0/ (ou a versão que você usa).