C# Palavras-chave
Palavras-chave são as palavras que o próprio C# usa: if, class, int, return… Esta página lista todas, cada uma com o que faz, um exemplo curto e a aula que ensina. Elas são de dois tipos: as reservadas, que nunca podem ser nome de variável, e as contextuais, que só são especiais em certos lugares do código.
As duas listas foram conferidas no compilador do laboratório (o dotnet 10.0.112, C# 14): cada palavra foi usada como nome de variável (int palavra = 1;), e as reservadas são exatamente as que deram erro.
Atalhos: Reservadas · Tipos · Valores · Decisões e laços · Exceções · Declarar tipos · Modificadores · Métodos e objetos · Operadores-palavra · Avançadas · Contextuais · Quando dá errado · Experimente
As palavras reservadas
São 77, todas em minúsculas. Nenhuma pode ser nome de variável, método ou classe (a não ser com @ na frente, veja Quando dá errado):
abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual void volatile while
Como o C# diferencia maiúsculas de minúsculas, Class, INT e If não são palavras-chave. Compilam, mas confundem quem lê: não use.
Tipos
Cada uma é um apelido para um tipo do .NET: int é o mesmo que System.Int32. Os tamanhos e limites estão em Tipos e Limites.
| Palavra | O que é | Exemplo | Aula |
|---|---|---|---|
bool | verdadeiro ou falso (System.Boolean) | bool aberto = true; | char e bool |
char | um caractere (System.Char) | char letra = 'A'; | char e bool |
byte, sbyte | inteiro de 8 bits, sem e com sinal | byte idade = 29; | Inteiros |
short, ushort | inteiro de 16 bits, com e sem sinal | short ano = 2026; | Inteiros |
int, uint | inteiro de 32 bits, com e sem sinal (o int é o padrão) | int estoque = 40; | Inteiros |
long, ulong | inteiro de 64 bits, com e sem sinal | long populacao = 213_000_000; | Inteiros |
float, double | número com vírgula de 32 e 64 bits (o double é o padrão) | double altura = 1.65; | float, double e decimal |
decimal | número com vírgula exato, de 128 bits: para dinheiro | decimal preco = 15.90m; | float, double e decimal |
string | texto (System.String) | string nome = "Ana"; | Strings |
object | o tipo de onde todos os outros descendem (System.Object) | object qualquer = 42; | A Classe object |
void | "nada": o método não devolve valor | static void Saudar() { … } | Métodos |
Valores
| Palavra | O que é | Exemplo | Aula |
|---|---|---|---|
true, false | os dois valores do bool | bool pago = false; | char e bool |
null | "nenhum objeto"; também "sem valor" num int? | string? apelido = null; | null |
default | o valor padrão de um tipo (0, false, null); também o "senão" do switch | int zero = default; | switch |
Decisões e laços
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
if, else | executa um bloco se a condição for verdadeira; senão, o outro | if (nota >= 7) { … } else { … } | if e else |
switch, case | escolhe um caminho pelo valor; também a expressão x switch { … } | switch (opcao) { case "1": … break; } | switch, Expressões switch |
while | repete enquanto a condição for verdadeira | while (saldo > 0) { … } | while |
do | repete, testando no fim (roda pelo menos uma vez) | do { … } while (resposta != "s"); | do while |
for | repete com contador | for (int i = 0; i < 10; i++) { … } | for |
foreach, in | passa por cada item de uma coleção | foreach (string item in compras) { … } | foreach |
break | sai do laço ou do case | if (achou) break; | break e continue |
continue | pula para a próxima volta do laço | if (nota < 0) continue; | break e continue |
goto | pula para um rótulo ou para outro case (goto case 2;). Quase nunca é a melhor ideia | goto case "1"; | switch |
return | termina o método e, se for o caso, devolve o valor | return a + b; | Valor de Retorno |
Exceções e estouro
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
try, catch | tenta um bloco e trata a exceção, se vier | try { … } catch (FormatException) { … } | try e catch |
finally | bloco que roda sempre, com ou sem exceção | finally { Console.WriteLine("fim"); } | finally |
throw | lança uma exceção | throw new ArgumentException("vazio"); | throw |
checked | faz a conta de inteiros lançar OverflowException quando estoura | checked(int.MaxValue + x) | Inteiros |
unchecked | deixa a conta estourar e "dar a volta" sem erro (é o padrão) | unchecked(int.MaxValue + 1) | Inteiros |
Declarar tipos e organizar
| Palavra | O que declara | Exemplo | Aula |
|---|---|---|---|
class | uma classe (tipo de referência) | class Tarefa { … } | Classes e Objetos |
struct | uma struct (tipo de valor) | struct Ponto { … } | Structs |
enum | uma lista de constantes com nome | enum Dia { Seg, Ter, Qua } | Enums |
interface | um contrato: o que uma classe promete ter | interface IForma { double Area(); } | Interfaces |
delegate | um tipo que guarda um método; também um método anônimo | delegate int Operacao(int a, int b); | Delegates |
event | um evento, que avisa quem se inscreveu | public event Action? Mudou; | Eventos |
namespace | um "sobrenome" que agrupa tipos | namespace Lojinha; | Namespaces e using |
using | no topo: traz um namespace; num bloco: fecha o recurso no fim | using System.Text; · using var f = File.OpenRead(…); | Namespaces, using e IDisposable |
Modificadores
| Palavra | O que muda | Exemplo | Aula |
|---|---|---|---|
public | qualquer código pode usar | public string Nome { get; } | public, private e internal |
private | só dentro do próprio tipo (o padrão nos membros) | private int _saldo; | public, private e internal |
protected | o próprio tipo e as classes filhas | protected decimal taxa; | Herança |
internal | só dentro do mesmo projeto (o padrão nas classes) | internal class Ajudante { … } | public, private e internal |
static | pertence ao tipo, não a cada objeto | static int contador; | static |
const | constante, decidida na compilação | const int MaxItens = 100; | Constantes |
readonly | campo que só recebe valor na declaração ou no construtor | private readonly List<int> _notas = []; | readonly e init |
abstract | classe que não se instancia; método sem corpo, que a filha tem de escrever | abstract class Forma { public abstract double Area(); } | Classes Abstratas |
virtual | método que as filhas podem substituir | public virtual string Falar() => "…"; | virtual e override |
override | substitui o método virtual ou abstract da mãe | public override string ToString() => Nome; | virtual e override |
sealed | classe que não pode ter filhas; override que não pode ser substituído de novo | sealed class Senha { … } | sealed |
new (modificador) | esconde, de propósito, um membro de mesmo nome da mãe | public new void Mostrar() { … } | Herança |
extern | método escrito fora do C# (numa biblioteca do sistema), usado com [DllImport] | static extern int getpid(); | Atributos |
volatile | campo lido e escrito por várias threads sem cache | volatile bool parar; | Threads |
Métodos, parâmetros e objetos
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
new (operador) | cria um objeto | var lista = new List<int>(); | Classes e Objetos |
this | o próprio objeto; também o primeiro parâmetro de um método de extensão | this.nome = nome; | this |
base | a classe mãe: chama o construtor ou o método dela | : base(nome) · base.ToString() | base |
ref | passa a própria variável, não uma cópia | Dobrar(ref x); | ref, out e in |
out | parâmetro que o método preenche | int.TryParse(texto, out int n) | ref, out e in |
in (parâmetro) | passa por referência, só para leitura | static double Medir(in Ponto p) | ref, out e in |
params | aceita quantos argumentos vierem | static int Somar(params int[] n) | params |
operator | define o que um operador (+, ==…) faz com o seu tipo | public static Ponto operator +(Ponto a, Ponto b) | Sobrecarga de Operadores |
implicit, explicit | conversão que acontece sozinha, ou só com cast | public static implicit operator decimal(Reais r) | Sobrecarga de Operadores |
lock | só uma thread por vez entra no bloco | lock (_trava) { saldo += valor; } | Sincronização (lock) |
Operadores que são palavras
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
is | testa o tipo ou um padrão | if (forma is Circulo c) { … } | Pattern Matching |
as | converte para um tipo de referência, ou dá null se não der | Circulo? c = forma as Circulo; | Polimorfismo |
typeof | o objeto Type que descreve um tipo | typeof(int).Name → Int32 | Reflexão |
sizeof | o tamanho em bytes de um tipo de valor | sizeof(int) → 4 | Tipos e Limites |
Avançadas (código inseguro e memória)
| Palavra | O que faz | Exemplo | Aula |
|---|---|---|---|
unsafe | libera ponteiros num bloco (precisa de <AllowUnsafeBlocks> no .csproj) | unsafe { int* p = &x; } | Memória |
fixed | prende um objeto na memória enquanto um ponteiro aponta para ele | fixed (char* p = texto) { … } | Memória |
stackalloc | reserva um bloco na pilha, em geral para um Span | Span<int> v = stackalloc int[8]; | Span<T> |
Palavras-chave contextuais
Estas só têm significado especial em certos lugares. Fora deles, são nomes comuns: string var = "ok"; e int record = 14; compilam. Por isso o C# pôde ganhar palavras novas (como record, em 2020, e field, em 2025) sem quebrar programas antigos que já usavam esses nomes. Mesmo assim, evite usá-las como nome: confunde quem lê.
| Palavra | Onde é especial e o que faz | Exemplo | Desde | Aula |
|---|---|---|---|---|
var | na declaração: "o compilador descobre o tipo" | var total = 0m; | C# 3 | var |
get, set | numa propriedade: o leitor e o gravador | public int Idade { get; set; } | C# 1 | Propriedades |
value | dentro do set: o valor que está chegando | set => _idade = value; | C# 1 | Propriedades |
field | dentro de um get/set: o campo escondido da propriedade, sem precisar declarar um | set => field = value.Trim(); | C# 14 | Propriedades |
init | numa propriedade: só recebe valor na criação do objeto | public string Nome { get; init; } | C# 9 | readonly e init |
required | numa propriedade: quem cria o objeto tem de preencher | public required string Nome { get; init; } | C# 11 | Inicializadores e required |
record | declara um record (classe ou struct de dados) | record Produto(string Nome, decimal Preco); | C# 9 | Records |
with | depois de um record ou struct: cópia com algumas mudanças | p with { Preco = 9.90m } | C# 9 | Records |
partial | tipo ou método dividido em vários arquivos | partial class Tela { … } | C# 2 | Classes Parciais |
file | antes de um tipo: ele só existe neste arquivo | file class Ajudante { … } | C# 11 | public, private e internal |
async, await | método assíncrono; esperar uma Task sem travar | string t = await File.ReadAllTextAsync("a.txt"); | C# 5 | async e await |
yield | num iterador: yield return entrega um item; yield break encerra | yield return i * i; | C# 2 | Iteradores |
nameof | o nome de uma variável, propriedade ou tipo, como texto | nameof(titulo) → "titulo" | C# 6 | throw |
when | condição extra num catch ou num case | catch (IOException e) when (e.HResult == 2) | C# 6 | try e catch |
and, or, not | combinam padrões | if (nota is >= 0 and <= 10) · if (x is not null) | C# 9 | Pattern Matching |
where | restrição de um genérico (e filtro na sintaxe de consulta do LINQ) | class Caixa<T> where T : IComparable<T> | C# 2 | Restrições (where) |
notnull, unmanaged | restrições de genérico: "não anulável"; "tipo de valor sem referências dentro" | where T : notnull | C# 8 / C# 7.3 | Restrições (where) |
allows | restrição que aceita ref struct (como Span<T>) num genérico | where T : allows ref struct | C# 13 | Restrições (where) |
from, select, orderby, ascending, descending, group, by, into, join, on, equals, let | a sintaxe de consulta do LINQ, parecida com SQL | from p in estoque where p.Qtd < 5 orderby p.Nome select p.Nome | C# 3 | O que é LINQ |
add, remove | num evento: o que fazer no += e no -= | add { _lista += value; } | C# 1 | Eventos |
extension | bloco de membros de extensão para um tipo | extension(string s) { public string Gritar() => …; } | C# 14 | Métodos de Extensão |
global | global using (vale para o projeto todo) e global:: (a raiz dos namespaces) | global using System.Text; | C# 10 / C# 2 | Namespaces e using |
alias | extern alias: dois pacotes com nomes iguais | extern alias Antiga; | C# 2 | Pacotes NuGet |
dynamic | tipo checado só na hora de rodar | dynamic x = 5; x = "texto"; | C# 4 | Reflexão |
nint, nuint | inteiro do tamanho de um endereço: 64 bits no laboratório, 32 no editor do guia (nint.Size dá 8 e 4) | nint n = 10; | C# 9 | Tipos e Limites |
scoped | limita até onde uma referência (ref, Span) pode ir | static void Ler(scoped Span<int> v) | C# 11 | Span<T> |
managed | convenção de chamada de um ponteiro de função | delegate* managed<int, int> f; | C# 9 | Memória |
args não é palavra-chave
Nas instruções de nível superior, args é só o nome do parâmetro que recebe a linha de comando (aula Argumentos da Linha de Comando). O mesmo vale para Main, Console e List: são nomes do .NET, não da linguagem.
Duas contextuais em ação: field C# 14 poupa declarar o campo de uma propriedade que limpa o texto, e extension C# 14 acrescenta um método ao string:
Produto p = new() { Nome = " caderno " };
Console.WriteLine($"[{p.Nome}]");
Console.WriteLine("lojinha".Gritar());
class Produto
{
public string Nome
{
get => field;
set => field = value.Trim();
} = "";
}
static class Extensoes
{
extension(string s)
{
public string Gritar() => s.ToUpper() + "!";
}
}
$ dotnet run novos.cs [caderno] LOJINHA!
Quando dá errado
A Ana calculava a área de um triângulo e chamou a variável de base, como na aula de matemática:
double base = 4;
double altura = 3;
Console.WriteLine($"Área: {base * altura / 2}");
$ dotnet run triangulo.cs /home/ana/cs/kw/triangulo.cs(1,8): error CS1001: Identificador esperado /home/ana/cs/kw/triangulo.cs(1,8): error CS1003: Erro de sintaxe, "," esperado Ocorreu uma falha no build. Corrija os erros de build e execute novamente.
O que significa: "identificador esperado" (em inglês, Identifier expected): depois de double, o compilador esperava um nome, e encontrou base, que é uma palavra da linguagem (a classe mãe, aula base). A segunda mensagem é consequência da primeira. Com outras palavras, a cascata pode ser bem maior: int class = 5; deu 13 erros no laboratório, todos por causa da mesma palavra.
Como consertar: o melhor é trocar o nome: baseTriangulo, lado. Se o nome tem mesmo de ser aquele (por exemplo, um campo de um JSON chamado "class"), ponha @ na frente: @base, @class. O @ diz "isto é um nome, não a palavra-chave", e não faz parte do nome.
int @class = 5;
string var = "contextual";
int record = 14;
Console.WriteLine($"{@class} {var} {record}");
$ dotnet run arroba.cs 5 contextual 14
Experimente
Missão: este é o programa do triângulo, com o erro CS1001. Conserte do jeito que preferir (trocando o nome da variável nas duas linhas, ou com @) para a saída ser Área: 6.
double base = 4;
double altura = 3;
Console.WriteLine($"Área: {base * altura / 2}");
double lado = 4;
double altura = 3;
Console.WriteLine($"Área: {lado * altura / 2}");
Resumo
- O C# 14 tem 77 palavras reservadas, todas em minúsculas. Nenhuma pode ser nome, a não ser com
@(@class). - Usar uma reservada como nome dá
CS1001: Identificador esperado, às vezes com uma cascata de outros erros na mesma linha. - As contextuais (
var,record,async,field…) só são especiais em certos lugares; fora deles, são nomes comuns. É assim que a linguagem ganha palavras novas sem quebrar código antigo. - Os tipos (
int,string,bool…) são apelidos de tipos do .NET:int=System.Int32. args,MaineConsolenão são palavras-chave.