Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Tip
Este artigo faz parte da secção Fundamentos para programadores que já conhecem pelo menos uma linguagem de programação e estão a aprender C#. Se és novo na programação, começa primeiro pelos tutoriais para começar .
Vem de outra língua? As expressões em C# funcionam de forma semelhante a Java, C++ e JavaScript. Uma diferença a notar: operadores de atribuição composta como += e o operador ++ de incremento são expressões em C#, pelo que podem aparecer em expressões maiores.
Uma expressão é um pedaço de código que o compilador avalia para produzir um valor — um número, uma cadeia, uma referência ou um bool. Por exemplo, 3 + 4 * 2 é uma expressão que é avaliada como o inteiro 11, e total > 10 é uma expressão que é avaliada como true ou false.
As expressões mais simples são literais (como 42 ou "hello") e nomes de variáveis (como total). Constroem expressões mais complexas combinando expressões mais simples com operadores.
Expressões e declarações
Uma expressão produz um valor. Uma declaração é uma instrução completa que o programa executa. Muitas afirmações contêm expressões. Por exemplo, int total = 3 + 4 * 2; é uma declaração de variável. O compilador avalia a expressão 3 + 4 * 2inicializadora , que produz 11, e atribui esse valor à nova variável total.
Podes pensar numa expressão como uma frase e numa afirmação em C# como uma frase completa. Estas definições de trabalho ajudam-no a compreender a terminologia formal e as explicações que encontrará à medida que aprende mais sobre C#, embora a programação comum raramente exija que lembre conscientemente a distinção.
Combinação de expressões
As expressões podem ser combinadas. Considere 3 + 4 * 2. Esta única expressão contém na verdade duas expressões menores: a expressão 4 * 2de multiplicação e a expressão3 + <result> de adição. Quando as expressões são combinadas, C# precisa de uma regra para decidir qual delas avaliar primeiro. Essa regra é a precedência do operador.
Não precisas de memorizar toda a hierarquia de precedência. A secção seguinte resume os grupos do dia a dia, e os parênteses permitem sempre que a ordem seja explícita quando tem dúvidas.
Precedência dos operadores
A precedência do operador determina como uma expressão combinada se agrupa em subexpressões. Este conceito é semelhante às regras de ordem de operações da aula de matemática. Um operador com precedência superior liga-se mais apertadamente aos seus operandos. A expressão está estruturada como se esses operandos estivessem entre parênteses. Em 3 + 4 * 2, * tem precedência superior à +, pelo que a expressão agrupa como 3 + (4 * 2), não (3 + 4) * 2.
C# tem mais grupos de precedência do que os quatro aqui resumidos. Esses grupos adicionais impõem regras familiares — por exemplo, multiplicação antes da adição — e abrangem o conjunto completo de operadores. Os seguintes grupos cobrem aquilo que mais frequentemente encontra no código do dia a dia:
-
Primário, unário e de alcance — são três grupos de precedência distintos, todos eles ligados de forma mais apertada do que a aritmética. Este resumo junta-os numa só etapa porque, para fins práticos, todos se aplicam antes da aritmética.
-
Os operadores primários — acesso membro (
x.y), chamadas de método (f()), indexação (a[i]) e acesso condicional nulo (?.,?[]) — vinculam de forma mais apertada de todos. -
Operadores unários atuam sobre um único operando: negação (
-x), lógica NOT (!flag), incremento prefixo (++i) e incremento pós-fixo (i++). - O operador de intervalo (
..) constrói intervalos de índice para expressões de fatia, comoarray[1..4].
-
Os operadores primários — acesso membro (
-
Aritmética —
*,/,%liga mais apertadamente do que+e-. A multiplicação e a divisão acontecem antes da adição e subtração. -
Comparação —
<,>,<=,>=,==,!=têm menor precedência do que os operadores aritméticos, pelo que as operações aritméticas são efetuadas antes da comparação. -
Lógico —
&&e||ligam o menos apertado dos operadores comuns, por isso as comparações são concluídas antes da combinação lógica.
Esta precedência significa que a expressão score + bonus > threshold && attempts < maxAttempts avalia exatamente como a leria: somar score e bonus, comparar a soma com threshold, comparar attempts com maxAttempts, e depois combinar os dois bool resultados com &&. Adicionar parênteses para tornar cada agrupamento explícito mostra a mesma estrutura: ((score + bonus) > threshold) && (attempts < maxAttempts).
Para a hierarquia completa de precedência que cobre todos os operadores, veja operadores e expressões C#.
Use parênteses para deixar a intenção clara
Parênteses sobrepõem-se à precedência e documentam a sua intenção ao mesmo tempo. Quando a ordem não for óbvia nos grupos acima, adicione parênteses:
int score = 80;
int bonus = 15;
int threshold = 90;
bool eligible = true;
// Without parentheses: || binds less tightly than &&, so this reads as:
// eligible && (score + bonus > threshold) || bonus > 20
bool result1 = eligible && score + bonus > threshold || bonus > 20;
// With parentheses: forces the || to combine two complete conditions
bool result2 = (eligible && score + bonus > threshold) || bonus > 20;
Console.WriteLine(result1); // => True
Console.WriteLine(result2); // => True
// Parentheses can also change the result:
bool isAdmin = false;
bool isOwner = true;
// Without: && binds tighter, so: (isAdmin && isOwner) || true
bool access1 = isAdmin && isOwner || true;
// With: forces the || to run first
bool access2 = isAdmin && (isOwner || true);
Console.WriteLine(access1); // => True (false && true is false; false || true is true)
Console.WriteLine(access2); // => False (false && anything is false)
As duas últimas linhas mostram que parênteses podem alterar o resultado, não apenas o estilo. Quando && e || aparecerem juntos, adiciona parênteses para indicar qual condição se combina primeiro. Um leitor que vê (isAdmin && isOwner) || isSuperUser percebe imediatamente a intenção.
Como as expressões são avaliadas
Compreender como C# avalia expressões combinadas é mais fácil com uma analogia. Pense em resolver um problema matemático complexo com lápis e papel: identifica a subexpressão mais interna ou de maior precedência, calcula o seu valor intermédio, escreve o resultado e repete com a próxima subexpressão — continuando até chegar à resposta final.
C# segue o mesmo processo, guiado por duas regras:
Regra 1: Os operandos são avaliados da esquerda para a direita. Para qualquer expressão binária, ambos os operandos devem ser totalmente avaliados antes de o operador ser aplicado. C# avalia primeiro o operando esquerdo, depois o direito, e depois executa a operação.
Regra 2: Alguns operadores fazem curto-circuito. Certos operadores deixam de avaliar assim que o resultado é determinado, saltando quaisquer operandos restantes:
-
&&(condicional AND): retornafalseassim que o lado esquerdo forfalse. O lado direito nunca é avaliado. -
||(OR condicional): retornatrueassim que o lado esquerdo fortrue. O lado direito nunca é avaliado. -
?:(condicional/ternário): avalia apenas o ramo que corresponde à condição — o outro ramo nunca é avaliado. -
?.(acesso de membro condicional nulo) e?[](acesso de elemento condicional nulo): param e retornamnullimediatamente quando o lado esquerdo énull, saltando o acesso ao membro ou índice. -
??=(atribuição de coalescimento nulo): atribui o lado direito apenas quando o lado esquerdo énull.
Avaliação em papel e lápis
Considere a expressão 3 + 6 / 2. Embora a adição apareça primeiro na ordem de leitura, / tenha precedência superior à +, também 6 / 2 é a subexpressão que avalia primeiro. Avançando passo a passo — exatamente como farias no papel:
3 + 6 / 2
↓ (evaluate 6 / 2 → 3)
3 + 3
↓ (evaluate 3 + 3 → 6)
6
// 3 + 6 / 2
// Step 1: 6 / 2 has higher precedence → interim value 3
// Step 2: 3 + 3 → final result 6
int result = 3 + 6 / 2;
Console.WriteLine(result); // => 6
O valor 3 intermédio produzido por 6 / 2 torna-se o operando direito de +, e o resultado final é 6. Cada subexpressão produz um valor intermediário; esses valores intermédios alimentam a próxima subexpressão, até que resta apenas um valor.
A associatividade é um conceito relacionado: quando dois operadores têm a mesma precedência, a associatividade decide qual deles começa primeiro. A maioria dos operadores C# são associativos à esquerda, ou seja, agrupam-se da esquerda para a direita. Portanto, a - b - c é o mesmo que (a - b) - c, não a - (b - c).
Avaliação de curtos-circuitos na prática
A avaliação de curtos-circuitos é particularmente útil para verificações nulas:
string? text = null;
// Safe: second condition runs only when text is not null
bool hasContent = text != null && text.Length > 0;
Console.WriteLine(hasContent); // => False (short-circuits after null check; no NullReferenceException)
text = "hello";
hasContent = text != null && text.Length > 0;
Console.WriteLine(hasContent); // => True
// || short-circuits on true: right side is never evaluated when left side is true
string word = "hello";
bool anyMatch = word.StartsWith("h") || word.StartsWith("x");
Console.WriteLine(anyMatch); // => True (right side never evaluated)
// ?. short-circuits on null: returns null without accessing .Length
string? maybeNull = null;
int? length = maybeNull?.Length; // length is null; no NullReferenceException
Console.WriteLine(length.HasValue); // => False
text != null && text.Length > 0 é seguro porque a segunda condição só é avaliada quando text não é null. De forma semelhante, ?. interrompe a avaliação quando encontra uma referência null, o que evita NullReferenceException sem uma verificação explícita de if.
Para uma visão mais ampla dos operadores null-safe, veja operadores nulos em C#.
Consulte também
- Operadores e expressões C# (referência de linguagem) — tabela de precedência completa e todos os operadores
- Aritmética, comparação, lógica e operadores de atribuição — os operadores do dia a dia em profundidade
-
Comparações de igualdade — como
==,!=, eEqualsfuncionam -
C# operadores nulos —
?.,??, e??= - Operadores lógicos booleanos