Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Dica
Este artigo faz parte da seção Conceitos Básicos para desenvolvedores que já conhecem pelo menos uma linguagem de programação e estão aprendendo C#. Se você é novo em programação, comece com os tutoriais Comece agora.
Vindo de outro idioma? As expressões em C# funcionam tanto quanto em Java, C++e JavaScript. Uma diferença que vale a pena observar: operadores de atribuição composta como += e o operador ++ de incremento são expressões em C#, para que possam aparecer em expressões maiores.
Uma expressão é uma parte do código que o compilador avalia para produzir um valor – um número, uma cadeia de caracteres, uma referência ou um bool. Por exemplo, 3 + 4 * 2 é uma expressão que é avaliada como o inteiro 11e 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). Você cria expressões mais complexas combinando as mais simples com operadores.
Expressões e declarações
Uma expressão produz um valor. Um comando é uma instrução completa que o programa executa. Muitas declarações contêm expressões. Por exemplo, int total = 3 + 4 * 2; é uma instrução de declaração de variável. O compilador avalia a expressão 3 + 4 * 2inicializador, que produz 11e atribui esse valor à nova variável total.
Você pode pensar em uma expressão como uma frase e uma instrução C# como uma frase completa. Essas definições de trabalho ajudam você a entender a terminologia formal e as explicações que você encontrará à medida que aprender mais sobre C#, embora a codificação comum raramente exija que você se lembre da distinção conscientemente.
Combinando expressões
Expressões podem ser combinadas. Considere o 3 + 4 * 2. Essa única expressão contém duas expressões menores: a expressão4 * 2 de multiplicação e a expressão de adição3 + <result>. Quando as expressões são combinadas, o C# precisa de uma regra para decidir qual delas avaliar primeiro. Essa regra é precedência de operador.
Você não precisa memorizar a hierarquia de precedência completa. A próxima seção resume os grupos cotidianos e os parênteses sempre permitem que você torne a ordem explícita quando não tiver certeza.
Precedência do operador
A precedência do operador determina como uma expressão combinada se agrupa em subexpressões. Esse conceito é semelhante às regras de ordem de operações da classe matemática. Um operador com precedência mais alta associa-se mais fortemente aos seus operandos. A expressão é estruturada como se esses operandos estivessem agrupados entre parênteses. Em 3 + 4 * 2, * tem precedência sobre +, portanto, a expressão é agrupada como 3 + (4 * 2), não como (3 + 4) * 2.
O C# tem mais grupos de precedência do que os quatro resumidos aqui. 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 abrangem o que você encontra com mais frequência no código cotidiano:
-
Primário, unário e intervalo – são três grupos de precedência distintos, todos os quais se associam mais fortemente do que a aritmética. Este resumo os combina em uma etapa porque, para fins práticos, todos se aplicam antes da aritmética.
-
Operadores primários – acesso de membro (
x.y), chamadas de método (f()), indexação (a[i]) e acesso condicional nulo (?.,?[]) – associam mais fortemente de todos. -
Operadores unários atuam em um único operando: negação (
-x), NOT lógico (!flag), incremento de prefixo (++i) e incremento de postfixo (i++). - O operador de intervalo (
..) cria intervalos de índice para expressões de fatia, comoarray[1..4].
-
Operadores primários – acesso de membro (
-
Aritmética —
*,%,/se associam mais fortemente do que+e-. Multiplicação e divisão ocorrem antes da adição e da subtração. -
Comparação —
<,>,<=,>=,==,!=se vinculam menos fortemente do que a aritmética, portanto a aritmética é concluída antes da comparação. -
Lógico –
&&e||associe menos fortemente os operadores comuns, portanto, as comparações são concluídas antes da combinação lógica.
Essa precedência significa que a expressão score + bonus > threshold && attempts < maxAttempts é avaliada exatamente como você a leria: adicionar score ebonus, comparar a soma comthreshold, comparar maxAttemptsattempts e 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 obter a hierarquia de precedência completa que abrange todos os operadores, consulte operadores e expressões em C#.
Usar parênteses para deixar a intenção clara
Os parênteses substituem a precedência e documentam sua intenção ao mesmo tempo. Quando a ordem não for óbvia dos 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, adicione parênteses para deixar claro qual condição é combinada primeiro. Um leitor que vê (isAdmin && isOwner) || isSuperUser sabe a intenção imediatamente.
Como as expressões são avaliadas
Entender como o C# avalia expressões combinadas é mais fácil com uma analogia. Pense em trabalhar em um problema matemático complexo com lápis e papel: você identifica a subexpressão mais interna ou de precedência mais alta, calcula seu valor provisório, anota o resultado e, em seguida, repete com a próxima subexpressão, continuando até chegar à resposta final.
O 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 que o operador seja aplicado. C# avalia o operando esquerdo primeiro, depois a direita e, em seguida, executa a operação.
Regra 2: Alguns operadores fazem curto-circuito. Determinados operadores param de avaliar assim que o resultado é determinado, ignorando todos os operandos restantes:
-
&&(AND condicional): retornafalseassim que o lado esquerdo éfalse. O lado direito nunca é avaliado. -
||(OR condicional): retornatrueassim que o lado esquerdo étrue. O lado direito nunca é avaliado. -
?:(condicional/ternário): avalia apenas o branch que corresponde à condição — o outro branch nunca é avaliado. -
?.(acesso de membro condicional nulo) e?[](acesso de elemento condicional nulo): pare e retornenullimediatamente quando o lado esquerdo estivernull, ignorando o acesso ou o índice do membro. -
??=(atribuição de coalescência nula): atribui o lado direito somente 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, / tem precedência maior do que +, assim 6 / 2 como a subexpressão que é avaliada primeiro. Trabalhar com ele passo a passo , exatamente como você faria 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 provisório produzido por 6 / 2 torna-se o operando certo de +, e o resultado final é 6. Cada subexpressão produz um valor intermediário; esses valores intermediários alimentam a próxima subexpressão, até que reste apenas um valor.
Associatividade é um conceito relacionado: quando dois operadores têm a mesma precedência, a associatividade decide qual deles vai primeiro. A maioria dos operadores C# são associativos à esquerda, o que significa que eles agrupam da esquerda para a direita. Assim a - b - c é o mesmo que (a - b) - c, não a - (b - c).
Avaliação de curto-circuito na prática
A avaliação de curto-circuito é 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 é executada somente quando text não é null. Da mesma forma, ?. interrompe a avaliação quando encontra uma referência null, o que evita um(a) NullReferenceException sem uma verificação explícita de if.
Para obter uma visão mais ampla dos operadores nulos seguros, consulte 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
- Operadores aritméticos, de comparação, lógicos e de atribuição – os operadores cotidianos em profundidade
-
Comparações de igualdade — como
==,!=eEqualsfuncionam -
Operadores nulos do C# —
?.e????= - Operadores lógicos boolianos