C# Métodos

Até aqui, todo o seu programa era uma lista de linhas, de cima para baixo. Isso funciona para programas pequenos, mas logo aparecem trechos repetidos, e o arquivo vira uma parede de Console.WriteLine. Um método é um pedaço de código com nome: você escreve as instruções uma vez e, depois, sempre que precisar, chama o nome. Nesta aula você vai criar seus primeiros métodos, entender em que ordem as linhas rodam e descobrir um detalhe importante do C# moderno: os métodos que você escreve no fim de um arquivo como o ola.cs são, na verdade, funções locais.

Você vai aprender
  • O que é um método e por que ele deixa o programa mais curto e mais fácil de consertar.
  • Como declarar um método (escrever) e como chamar (usar).
  • Em que ordem as linhas rodam quando o programa entra e sai de um método.
  • O que quer dizer o void antes do nome.
  • Onde o método fica: no fim do arquivo (uma função local) ou dentro de uma classe, com static.
  • Os erros mais comuns: CS0103, CS1501, CS0029, CS0201, CS0128, CS0120 e o aviso CS8321.

Todos os programas desta aula rodaram na máquina fictícia da Ana (usuária ana, computador notebook), na pasta ~/cs, com o .NET 10 e o comando que você aprendeu em Rodar com dotnet run: dotnet run arquivo.cs. Você pode repetir cada um no editor do guia, que compila e roda C# de verdade no navegador.


A ideia: uma receita com nome

Pense no caderno de receitas da avó da Ana. Lá está escrito, uma vez só, como fazer a massa básica. Depois, a receita de pizza diz apenas "faça a massa básica", e a de pão também. Ninguém copia o passo a passo da massa em cada receita: basta citar o nome.

No caderno de receitasEm C#Nome técnico
Escrever, uma vez, como se faz a massa básicaEscrever o nome do método e, entre { }, as instruçõesdeclarar o método
"Agora, faça a massa básica"Escrever o nome do método seguido de ()chamar o método
Voltar para a receita da pizza e continuarO programa volta para a linha seguinte à chamadaretornar

Escrever a receita no caderno não faz pizza nenhuma. Só quando alguém segue a receita a massa aparece. Em C# é igual: declarar um método não executa nada; ele só roda quando é chamado.

Você já usa métodos desde a primeira aula, só que escritos por outras pessoas: Console.WriteLine ("escrever linha no console") é um método da biblioteca do .NET, Math.Sqrt é outro, texto.ToUpper() também. Agora você vai escrever os seus.


1. O problema: código repetido

A Ana imprime um recibo para cada venda da lojinha. Sem métodos, a linha de = aparece repetida quatro vezes:

Console.WriteLine("==============================");
Console.WriteLine("  LOJINHA DA ANA");
Console.WriteLine("==============================");
Console.WriteLine("Caderno ......... R$ 12,50");
Console.WriteLine("Caneta .......... R$  3,00");
Console.WriteLine("==============================");
Console.WriteLine("Total ........... R$ 15,50");
Console.WriteLine("==============================");
$ dotnet run recibo1.cs
==============================
  LOJINHA DA ANA
==============================
Caderno ......... R$ 12,50
Caneta .......... R$  3,00
==============================
Total ........... R$ 15,50
==============================

Funciona, mas a linha de sinais de igual está escrita quatro vezes. Se a Ana quiser trocar = por -, precisa lembrar de corrigir em todos os lugares. Com dez recibos, seriam dezenas de cópias. É aqui que entra o método.


2. Seu primeiro método

A Ana coloca a linha num método chamado Linha, no fim do arquivo, e troca cada cópia por uma chamada:

Linha();
Console.WriteLine("  LOJINHA DA ANA");
Linha();
Console.WriteLine("Caderno ......... R$ 12,50");
Console.WriteLine("Caneta .......... R$  3,00");
Linha();
Console.WriteLine("Total ........... R$ 15,50");
Linha();

void Linha()
{
    Console.WriteLine("==============================");
}
$ dotnet run recibo2.cs
==============================
  LOJINHA DA ANA
==============================
Caderno ......... R$ 12,50
Caneta .......... R$  3,00
==============================
Total ........... R$ 15,50
==============================

A saída é idêntica à do recibo1.cs. O que mudou foi o código: a linha está escrita uma vez só. Para trocar o desenho, basta editar uma linha.

Anatomia da declaração

Vamos olhar o método parte por parte:

void
"Vazio": o método não devolve nenhum valor para quem o chamou. Ele só faz uma coisa (aqui, escrever na tela) e termina. Métodos que devolvem um resultado, como um total calculado, ficam para Valor de Retorno.
Linha
O nome, escolhido por você. Segue as regras dos nomes de variáveis (Nomes e Convenções), mas, em C#, nomes de métodos começam com letra maiúscula e juntam as palavras com maiúsculas (PascalCase): Linha, MostrarRecibo, CalcularTotal. Use um verbo, ou algo que diga o que o método faz.
( )
Os parênteses, obrigatórios. Aqui estão vazios: o método não recebe nenhuma informação. Quando ele precisar receber dados (um nome, um preço), eles vão aqui dentro: é a aula Parâmetros.
{ … }
O corpo: as instruções que rodam cada vez que o método é chamado. Podem ser quantas linhas você quiser.

E a chamada:

Linha
O nome do método que você quer executar, escrito igualzinho à declaração. Maiúsculas e minúsculas contam: linha() é outro nome.
( )
Os parênteses dizem "execute agora". São obrigatórios, mesmo vazios.
;
Toda chamada é uma instrução e termina com ponto e vírgula, como o Console.WriteLine(…);.
Por que o método ficou no fim do arquivo?

Porque o programa da Ana é uma lista de instruções que começa na primeira linha. Se o método ficasse no meio, as instruções ficariam espalhadas e o arquivo seria difícil de ler. A regra do guia: primeiro as instruções do programa, depois os métodos. Na seção 4 você vai ver o que o compilador faz com eles.

Missão: crie, no fim do arquivo, um método MostrarRodape() que escreva Obrigada e volte sempre!, e chame-o na última linha do programa (antes dos métodos). Use o Linha como modelo.

Linha();
Console.WriteLine("  LOJINHA DA ANA");
Linha();
Console.WriteLine("Caderno ......... R$ 12,50");
Linha();

void Linha()
{
    Console.WriteLine("==============================");
}
Linha();
Console.WriteLine("  LOJINHA DA ANA");
Linha();
Console.WriteLine("Caderno ......... R$ 12,50");
Linha();
MostrarRodape();

void Linha()
{
    Console.WriteLine("==============================");
}

void MostrarRodape()
{
    Console.WriteLine("Obrigada e volte sempre!");
}

3. Em que ordem as linhas rodam

O programa sempre começa pela primeira instrução do arquivo, de cima para baixo. Quando encontra uma chamada, ele pula para dentro do método, executa o corpo inteiro e volta para a linha seguinte. Os números deste exemplo mostram a ordem:

Console.WriteLine("1. O programa começou");
Saudar();
Console.WriteLine("3. Voltei para o programa");
Saudar();
Console.WriteLine("5. Fim");

void Saudar()
{
    Console.WriteLine("   Olá! Eu sou o método Saudar.");
}
$ dotnet run ordem.cs
1. O programa começou
   Olá! Eu sou o método Saudar.          « passo 2: a primeira chamada
3. Voltei para o programa
   Olá! Eu sou o método Saudar.          « passo 4: a segunda chamada
5. Fim
PassoOnde o programa estáO que acontece
1linha 1Escreve 1. O programa começou.
2linha 2 → SaudarEncontra Saudar();, pula para o método (linha 9) e escreve a saudação. Ao chegar no } do método, volta.
3linha 3Continua de onde parou: escreve 3. Voltei para o programa.
4linha 4 → SaudarPula de novo para o método. A mesma receita, seguida outra vez.
5linha 5Escreve 5. Fim. Não há mais instruções: o programa termina.

Repare: quando o programa chega na linha 5, ele não continua descendo para dentro de Saudar por conta própria. O método fica parado no fim do arquivo, esperando ser chamado. Se ninguém chamar, ele nunca roda.

Um método pode chamar outro

Qualquer método pode chamar outros. A Ana organizou o dia da lojinha assim:

DiaDeTrabalho();

void AbrirLoja()
{
    Console.WriteLine("Lojinha da Ana: aberta!");
}

void MostrarProdutos()
{
    Console.WriteLine("Hoje temos: caderno, caneta, borracha");
}

void FecharLoja()
{
    Console.WriteLine("Lojinha da Ana: fechada. Até amanhã!");
}

void DiaDeTrabalho()
{
    AbrirLoja();
    MostrarProdutos();
    FecharLoja();
}
$ dotnet run dia.cs
Lojinha da Ana: aberta!
Hoje temos: caderno, caneta, borracha
Lojinha da Ana: fechada. Até amanhã!

O programa tem uma instrução só: DiaDeTrabalho();. Esse método chama os outros três, um de cada vez, e cada um volta para quem o chamou quando termina. Ler o programa agora é como ler um índice: "faça o dia de trabalho"; quem quiser os detalhes abre o método.

Repare também na ordem: DiaDeTrabalho foi escrito depois dos três que ele usa, mas a primeira linha do arquivo o chama antes de ele aparecer. Em C#, a ordem dos métodos não importa: o compilador lê o arquivo inteiro antes de montar o programa.

E se um método chamar a si mesmo?

Isso existe e tem nome: recursão. É uma técnica poderosa, mas exige cuidado para não virar uma repetição sem fim. Ela tem uma aula só para ela: Recursão.


4. Onde os métodos moram: funções locais

Agora o detalhe prometido. Em Program.cs e o Main você viu que um arquivo como o ola.cs, com as instruções soltas, é um atalho: o compilador embrulha essas instruções num método escondido, o Main, que é por onde todo programa C# começa. As instruções soltas se chamam instruções de nível superior (top-level statements) C# 9.

E os métodos que você escreveu no fim do arquivo? Eles também vão para dentro desse Main escondido. Um método declarado dentro de outro método se chama função local (local function) C# 7. Para o compilador, o recibo2.cs é mais ou menos isto:

class Program
{
    static void Main(string[] args)
    {
        Linha();
        Console.WriteLine("  LOJINHA DA ANA");
        // ... as outras instruções ...

        void Linha()        // função local: mora dentro do Main
        {
            Console.WriteLine("==============================");
        }
    }
}

Dá para ver isso com os próprios olhos. Quando um programa quebra, o .NET mostra o caminho das chamadas até o erro. Este método tenta ler a posição 5 de um array que só tem 2 posições (o erro de Arrays):

Console.WriteLine("Antes da chamada");
Quebrar();

void Quebrar()
{
    int[] notas = { 7, 8 };
    Console.WriteLine(notas[5]);
}
$ dotnet run prova.cs
Antes da chamada
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Program.<<Main>$>g__Quebrar|0_0() in /home/ana/cs/prova.cs:line 7
   at Program.<Main>$(String[] args) in /home/ana/cs/prova.cs:line 2
at Program.<Main>$(String[] args) … line 2
"Em Program.<Main>$": é o Main escondido, com o nome estranho que o compilador dá a ele. A chamada Quebrar(); está na linha 2.
at Program.<<Main>$>g__Quebrar|0_0() … line 7
O seu método. O nome completo, montado pelo compilador, diz "a função Quebrar, dentro de <Main>$". Esse g__ é a marca que o compilador põe nas funções locais. O erro aconteceu na linha 7.

Você não precisa decorar esses nomes. O que importa é saber que, num arquivo com instruções de nível superior, os seus métodos são funções locais do Main. Na prática, isso traz quatro consequências que você vai encontrar:

ConsequênciaO que você vê
A ordem não importa: dá para chamar antes de declararO DiaDeTrabalho(); da primeira linha funcionou
As mensagens do compilador falam em função localwarning CS8321: A função local 'Linha' está declarada, mas nunca é usada (veja em "Quando dá errado")
Uma função local enxerga as variáveis do programaÚtil, mas pode confundir; a aula Escopo mostra quando isso morde
Classes vêm depois de tudoSe você declarar uma class e escrever instruções depois dela, dá CS8803

A última linha da tabela, com o erro real:

Linha();

class Loja
{
}

Console.WriteLine("Fim");

void Linha()
{
    Console.WriteLine("==========");
}
$ dotnet run depoisclasse.cs
/home/ana/cs/depoisclasse.cs(7,1): error CS8803: As instruções de nível superior precisam preceder as declarações de namespace e de tipo.

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

Precisam preceder = "precisam vir antes". As instruções e as funções locais formam um bloco só, o Main; uma class (um "tipo") no meio corta esse bloco. Conserto: mova a class Loja para o fim do arquivo. Classes são assunto de Classes e Objetos.


5. A forma com static numa classe

Quase todo código C# escrito antes do .NET 6, e muito código de hoje, não usa instruções de nível superior. Ele escreve a classe e o Main por extenso, e os métodos ficam dentro da classe, ao lado do Main, com a palavra static:

class Program
{
    static void Main()
    {
        Linha();
        Console.WriteLine("  LOJINHA DA ANA");
        Linha();
    }

    static void Linha()
    {
        Console.WriteLine("==============================");
    }
}
$ dotnet run classe.cs
==============================
  LOJINHA DA ANA
==============================
class Program { … }
A classe, a "caixa" onde mora o código. Por enquanto, ela só serve de casa para os métodos (o que mais uma classe faz é o assunto do Nível 2, em Classes e Objetos).
static void Main()
O método por onde o programa começa, agora escrito por você. Ele é static porque o .NET o chama logo no início, quando ainda não existe nada criado.
static void Linha()
O seu método. Ele fica dentro da classe e fora do Main, como irmão do Main. Isso não é uma função local: é um método da classe. O static ("estático", "da classe") permite que o Main, que também é static, o chame direto.

Os dois arquivos (recibo2.cs e classe.cs) fazem a mesma coisa. Aqui também a ordem não importa: Linha poderia vir antes do Main. E o que acontece se você esquecer o static?

class Program
{
    static void Main()
    {
        Linha();
    }

    void Linha()
    {
        Console.WriteLine("==============================");
    }
}
$ dotnet run semstatic.cs
/home/ana/cs/semstatic.cs(5,9): error CS0120: Uma referência de objeto é necessária para o campo, o método ou a propriedade "Program.Linha()" não estática

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

Em inglês, An object reference is required for the non-static field, method, or property. Um método sem static pertence a um objeto, uma "coisa" criada a partir da classe, e o Main não tem objeto nenhum na mão. Enquanto você não aprende objetos, a regra é simples: dentro de uma classe, ao lado do Main, escreva static. A aula static explica o assunto por inteiro.

Missão: este programa não compila: dá CS0120. Conserte com uma palavra, sem mudar mais nada, e rode.

class Program
{
    static void Main()
    {
        Linha();
        Console.WriteLine("Recibo da lojinha");
        Linha();
    }

    void Linha()
    {
        Console.WriteLine("==========");
    }
}
class Program
{
    static void Main()
    {
        Linha();
        Console.WriteLine("Recibo da lojinha");
        Linha();
    }

    static void Linha()
    {
        Console.WriteLine("==========");
    }
}

Formas diferentes de escrever métodos

Você vai encontrar três jeitos, e os três compilam no .NET 10:

1. No fim de um arquivo com instruções de nível superior (a forma do guia)

É o que você fez nesta aula: void Linha() { … } depois das instruções. São funções locais do Main escondido.

2. O mesmo, com static

Muitos exemplos da internet (e da própria Microsoft) escrevem static também no fim de um arquivo com instruções de nível superior:

Linha();
Console.WriteLine("  LOJINHA DA ANA");
Linha();

static void Linha()
{
    Console.WriteLine("==============================");
}
$ dotnet run estatico.cs
==============================
  LOJINHA DA ANA
==============================

Continua sendo uma função local. O static, aqui, tem outro sentido: "esta função não usa as variáveis do programa" C# 8. Se ela tentar usar, o compilador reclama. A diferença só aparece quando há variáveis no meio, e é explicada em Funções Locais.

3. Numa classe, com static

A forma da seção 5. É a que você vai ver em projetos grandes, em livros e em código antigo, e a que o guia usa quando o programa passa a ter vários arquivos (Projetos).

Qual usar?

SituaçãoForma
Exercícios deste guia, programas de um arquivo (dotnet run arquivo.cs)Instruções no topo, void Nome() { … } no fim
Quer garantir que o método não mexe nas variáveis do programaA mesma, com static void Nome()
Projetos com vários arquivos, código que outras classes vão usar, código anterior ao .NET 6class + static void Nome() ao lado do Main
Método ou função?

Em outras linguagens (C, Python, JavaScript) você vai ouvir "função". Em C#, todo bloco de código com nome mora numa classe e se chama método (do inglês method, "modo de fazer"). A função local é um caso especial: um método que mora dentro de outro método. No dia a dia, quase todo mundo chama tudo de "método", e o guia também; o nome "função local" importa quando ele aparece numa mensagem do compilador.


Quando dá errado

error CS0103: O nome "Linah" não existe no contexto atual
$ dotnet run digitou.cs
/home/ana/cs/digitou.cs(1,1): error CS0103: O nome "Linah" não existe no contexto atual
/home/ana/cs/digitou.cs(3,6): warning CS8321: A função local 'Linha' está declarada, mas nunca é usada

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

O que significa: a linha 1 chama Linah(), mas o método se chama Linha. Em inglês: The name 'Linah' does not exist in the current context. O aviso que vem junto é consequência: como ninguém chamou o Linha de verdade, ele ficou sem uso. O mesmo erro aparece com linha() (minúscula).

Como consertar: confira o nome letra por letra, com maiúsculas e minúsculas. Conserte o erro e o aviso some junto.

error CS1501: Nenhuma sobrecarga para o método "Linha" leva 1 argumentos
$ dotnet run argumento.cs
/home/ana/cs/argumento.cs(1,1): error CS1501: Nenhuma sobrecarga para o método "Linha" leva 1 argumentos

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

O que significa: a chamada foi Linha(5);, mas o método não recebe nada. Argumento é o valor entre os parênteses da chamada; sobrecarga é uma versão do método (um método pode ter várias, veja Sobrecarga). Em inglês: No overload for method 'Linha' takes 1 arguments.

Como consertar: tire o valor (Linha();) ou, se o método deveria mesmo receber um número, acrescente um parâmetro (Parâmetros).

error CS0029: Não é possível converter implicitamente tipo "void" em "int"
$ dotnet run usarvoid.cs
/home/ana/cs/usarvoid.cs(1,9): error CS0029: Não é possível converter implicitamente tipo "void" em "int"

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

O que significa: a linha int x = Linha(); tenta guardar o "resultado" de um método void, que não devolve nada. Não há o que guardar em x.

Como consertar: chame o método sozinho na linha (Linha();). Se você precisa de um resultado, o método tem de devolver um, com outro tipo no lugar do void e um return (Valor de Retorno).

error CS0201: Somente as expressões de atribuição, chamada, incremento, diminuição, espera e novo objeto podem ser utilizadas como uma instrução
$ dotnet run semparen.cs
/home/ana/cs/semparen.cs(1,1): error CS0201: Somente as expressões de atribuição, chamada, incremento, diminuição, espera e novo objeto podem ser utilizadas como uma instrução

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

O que significa: a linha foi Linha;, sem parênteses. Sem eles, você só cita o nome do método, e citar um nome não é uma instrução: o compilador lista o que pode ficar sozinho numa linha, e "chamada" é uma delas.

Como consertar: escreva Linha();. Toda chamada leva parênteses, mesmo vazios.

error CS0128: Uma variável de local ou função denominada 'Linha' já está definida neste escopo
$ dotnet run duplo.cs
/home/ana/cs/duplo.cs(8,6): error CS0128: Uma variável de local ou função denominada 'Linha' já está definida neste escopo
/home/ana/cs/duplo.cs(8,6): warning CS8321: A função local 'Linha' está declarada, mas nunca é usada

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

O que significa: há dois void Linha() no arquivo, e a linha 8 é o segundo. Repare na palavra função (local): a mensagem vem do fato de os seus métodos morarem dentro do Main.

Como consertar: apague um deles ou dê outro nome (LinhaDupla, por exemplo).

error CS8112: A função local 'Linha()' deve declarar um corpo porque não está marcado como 'static extern'.
$ dotnet run pontovirg.cs
/home/ana/cs/pontovirg.cs(3,6): error CS8112: A função local 'Linha()' deve declarar um corpo porque não está marcado como 'static extern'.

Ocorreu uma falha no build. Corrija os erros de build e execute novamente.

O que significa: sobrou um ; no fim da declaração: void Linha(); seguido de {. Com o ;, a declaração termina ali, sem corpo, e as chaves da linha de baixo viram um bloco solto. Ignore o static extern: é um recurso avançado que você não vai usar.

Como consertar: na declaração, nada de ; entre o ) e a {. O ; vai na chamada.

warning CS8321: A função local 'Linha' está declarada, mas nunca é usada
$ dotnet run naousado.cs
/home/ana/cs/naousado.cs(3,6): warning CS8321: A função local 'Linha' está declarada, mas nunca é usada
Bom dia!

O que significa: é um aviso, não um erro: o programa rodou e mostrou Bom dia!. O compilador só está dizendo que você escreveu o método Linha e ninguém o chama. Em geral é esquecimento, ou um nome digitado errado na chamada.

Como consertar: chame o método onde ele deveria rodar, ou apague-o se não precisa mais dele.

error CS0120: Uma referência de objeto é necessária…

O que significa: numa classe, você chamou do Main um método escrito sem static (seção 5).

Como consertar: escreva static void Linha().


Referência rápida

EscritaO que faz
void Nome() { … }Declara um método que não recebe nada e não devolve nada
Nome();Chama o método: roda o corpo e volta para a linha seguinte
void antes do nomeO método não devolve valor
() vazio na declaraçãoO método não recebe valores
Método no fim de um arquivo com instruções de nível superiorFunção local do Main escondido; pode ser chamado de qualquer linha do programa
static void Nome() no fim desse arquivoFunção local que não usa as variáveis do programa
static void Nome() dentro de class ProgramMétodo da classe, chamado direto pelo static void Main()
PascalCase: MostrarReciboA convenção do C# para nomes de métodos

Exercícios

1. Chamar o método

Complete a linha que chama o método Apitar, declarado como void Apitar():

2. O tipo que não devolve nada

Complete a declaração de um método que só mostra um texto e não devolve valor:

Avisar()

3. Dentro da classe

Dentro de class Program, ao lado do static void Main(), qual palavra vem antes de void Menu() para o Main poder chamá-lo?

void Menu()

4. Um programa declara void Ola() no fim do arquivo, mas nenhuma linha chama Ola(). O que acontece?

5. Num arquivo com instruções de nível superior, o que são os métodos escritos no fim do arquivo?

6. A primeira linha do arquivo chama Fechar();, e o método Fechar está escrito na última linha. O que acontece?

Missão final: o recibo da lojinha

Missão: monte o recibo com três métodos, todos void e sem parâmetros, escritos no fim do arquivo:

  • Linha: mostra ========== (dez sinais de igual);
  • Cabecalho: chama Linha, mostra LOJINHA DA ANA (com dois espaços na frente) e chama Linha de novo;
  • Rodape: chama Linha e mostra Obrigada e volte sempre!.

As três instruções do programa já estão prontas. A saída tem de ser exatamente esta, sem avisos:

==========
  LOJINHA DA ANA
==========
Caderno   R$ 12,50
==========
Obrigada e volte sempre!
Cabecalho();
Console.WriteLine("Caderno   R$ 12,50");
Rodape();

// escreva aqui os métodos Linha, Cabecalho e Rodape
Cabecalho();
Console.WriteLine("Caderno   R$ 12,50");
Rodape();

void Linha()
{
    Console.WriteLine("==========");
}

void Cabecalho()
{
    Linha();
    Console.WriteLine("  LOJINHA DA ANA");
    Linha();
}

void Rodape()
{
    Linha();
    Console.WriteLine("Obrigada e volte sempre!");
}

Se você esqueceu de escrever um dos métodos, o compilador reclamou com CS0103. Se escreveu um método a mais e não o chamou, apareceu o aviso CS8321, e a meta "sem avisos" ficou de fora.


Resumo

  • Método = pedaço de código com nome. Declarar escreve a receita; chamar (Nome();) executa. O programa pula para o método e volta para a linha seguinte.
  • Métodos evitam código repetido: conserta-se num lugar só, e o programa fica mais fácil de ler e de dividir.
  • void antes do nome: não devolve nada. Parênteses vazios: não recebe nada. Nomes em PascalCase.
  • Num arquivo com instruções de nível superior, os métodos do fim do arquivo são funções locais do Main escondido: podem ser chamados de qualquer linha, e as mensagens do compilador falam em "função local".
  • Na forma com classe, os métodos ficam dentro de class Program, ao lado do Main, com static. Sem o static, dá CS0120.
  • Erros típicos: CS0103 (nome errado), CS1501 (argumento a mais), CS0029 (usar o resultado de um void), CS0201 (faltou o ()), CS0128 (nome repetido), CS8112 (; antes da {) e o aviso CS8321 (método nunca usado).