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? A maioria dos operadores neste artigo (+, -, , *, %/, , &&||, !, , ==, !=<, , , >, operadores de comparação e =) funcionam da mesma forma que em Java, C++e JavaScript. As principais surpresas para os recém-chegados são o comportamento da divisão inteira, a distinção entre prefixo e postfixo para ++/-- e a forma como a atribuição composta é convertida novamente para o tipo do lado esquerdo.
Um operador combina um ou mais operandos em um único valor. Você já sabe sobre expressões e precedência de operador de expressões C#; este artigo se aprofunda nos operadores específicos que você usará todos os dias.
Operadores aritméticos
Os cinco operadores aritméticos executam cálculos numéricos.
| Operador | Name | Exemplo | Resultado |
|---|---|---|---|
+ |
Adição | 10 + 3 |
13 |
- |
Subtração | 10 - 3 |
7 |
* |
Multiplicação | 10 * 3 |
30 |
/ |
Divisão | 10 / 3 |
3 |
% |
Pendência | 10 % 3 |
1 |
int apples = 10;
int oranges = 3;
Console.WriteLine(apples + oranges); // => 13 (addition)
Console.WriteLine(apples - oranges); // => 7 (subtraction)
Console.WriteLine(apples * oranges); // => 30 (multiplication)
Console.WriteLine(apples / oranges); // => 3 (integer division: truncates toward zero)
Console.WriteLine(apples % oranges); // => 1 (remainder)
// Integer division always truncates toward zero — the fractional part is discarded
int result = 7 / 2;
Console.WriteLine(result); // => 3, not 3.5
// Truncation applies to negative results too: -7 / 2 is -3, not -4
int negResult = -7 / 2;
Console.WriteLine(negResult); // => -3
// To get a decimal result, at least one operand must be a double or float
double precise = 7.0 / 2;
Console.WriteLine(precise); // => 3.5
// Remainder with negative operands: the sign of the result matches the dividend
Console.WriteLine(-7 % 3); // => -1 (-7 = 3 × -2 + (-1))
Console.WriteLine(7 % -3); // => 1 ( 7 = -3 × -2 + 1)
A divisão inteira trunca para zero. Quando ambos os operandos são inteiros, / descarta a parte fracionária: 7 / 2 é 3, não 3.5. O truncamento é em direção a zero, não para o número menor: -7 / 2 é -3 (não -4). Para obter um resultado decimal, faça com que pelo menos um operando seja um tipo de ponto flutuante: 7.0 / 2 é 3.5. Isso difere de algumas linguagens em que / sempre produz um resultado de ponto flutuante.
Resto (%) retorna o que resta após a divisão inteira: 10 % 3 é 1 porque 10 = 3 × 3 + 1. É útil para percorrer um intervalo fixo (index % length), testar a divisibilidade (n % 2 == 0) e extrair dígitos. Com operandos negativos, o sinal do resultado corresponde ao sinal do dividendo (o operando esquerdo): -7 % 3 é -1 e 7 % -3 é 1.
Operadores unários
Operadores unários operam sobre um único operando.
int temperature = 20;
int windChill = -5;
int heatIndex = +temperature; // unary +: value unchanged (rarely needed)
int coldFactor = -windChill; // unary -: negates the value → 5
Console.WriteLine(heatIndex); // => 20
Console.WriteLine(coldFactor); // => 5
bool isRaining = false;
bool isSunny = !isRaining; // logical NOT: flips true/false
Console.WriteLine(isSunny); // => True
-
+x(adição unária) – deixa o valor inalterado; raramente escrito explicitamente, mas válido. -
-x(sinal de menos unário) — nega o valor. -
!x(NÃO lógico) — invertetrueemfalseefalseemtrue. Você usará!com frequência:if (!list.Contains(item)).
Incrementar e decrementar
++ adiciona 1 e -- subtrai 1. Ambos têm uma forma prefixa e uma forma pós-fixa que diferem quanto ao valor retornado:
int counter = 5;
// Prefix: increment first, then use the new value
int a = ++counter;
Console.WriteLine(a); // => 6
Console.WriteLine(counter); // => 6
// Postfix: use the current value first, then increment
int b = counter++;
Console.WriteLine(b); // => 6 (value before increment)
Console.WriteLine(counter); // => 7 (incremented after)
// Decrement works the same way
int score = 10;
Console.WriteLine(score--); // => 10 (current value; score becomes 9)
Console.WriteLine(score); // => 9
-
Prefixo (
++i,--i): incrementa ou decrementa a variável primeiro e retorna o novo valor. -
Postfix (
i++,i--): retorna o valor atual primeiro, depois incrementa ou decrementa a variável.
Quando ++ ou -- aparece como uma instrução autônoma (não parte de uma expressão maior), o prefixo e o postfix têm o mesmo efeito. A distinção só importa quando o resultado é usado , por exemplo, em uma atribuição ou como um argumento de método.
Operadores relacionais
Operadores relacionais comparam dois valores e retornam um bool.
| Operador | Meaning | Exemplo |
|---|---|---|
< |
Menor que | speed < limit |
> |
Maior que | speed > limit |
<= |
Inferior ou igual | score <= 100 |
>= |
Maior ou igual | score >= 0 |
int speed = 75;
int limit = 60;
Console.WriteLine(speed > limit); // => True (greater than)
Console.WriteLine(speed < limit); // => False (less than)
Console.WriteLine(speed >= limit); // => True (greater than or equal)
Console.WriteLine(speed <= limit); // => False (less than or equal)
// Relational operators work on all numeric types and char
// char comparison uses the character's numeric Unicode code point, not alphabetical position
// 'B' (U+0042, value 66) is less than 'A' (U+0041, value 65)? No — 'A' (65) < 'B' (66)
char grade = 'B';
Console.WriteLine(grade >= 'A' && grade <= 'C'); // => True ('A'=65 <= 'B'=66 <= 'C'=67)
Os operadores relacionais funcionam em todos os tipos numéricos e char. Para char, a comparação usa o valor de ponto de código Unicode numérico do caractere, não qualquer ordenação alfabética ou específica do domínio. No exemplo de nota acima, 'B' é maior ou igual a 'A' porque 'B' tem o valor Unicode 66 e 'A' tem o valor Unicode 65 — os números determinam a comparação, não o significado das notas da letra.
Operadores de igualdade
== e != verifique se dois valores são iguais ou não.
!= é true quando os operandos não são iguais, e false quando são.
int expected = 42;
int actual = 42;
Console.WriteLine(actual == expected); // => True (values are equal)
Console.WriteLine(actual != expected); // => False (true when values are not equal)
string name = "Alice";
Console.WriteLine(name == "Alice"); // => True (string content matches)
Console.WriteLine(name == "alice"); // => False (case-sensitive)
int x = 5;
Console.WriteLine(x == 10); // => False
Para tipos numéricos e string, a igualdade testa os valores. Para tipos de referência, o padrão é a identidade (se duas variáveis apontam para o mesmo objeto), mas muitos tipos incluem string e record substituem isso para comparar o conteúdo. Para ver a imagem completa – como a igualdade funciona entre tipos de valor, tipos de referência, registros e structs – consulte comparações de igualdade.
Note
O C# não tem um === operador. Escrever === é um erro em tempo de compilação:
// This does not compile — C# has no === operator
bool same = (x === 10);
Se você estiver vindo do JavaScript, use == para comparação de valor (C# == já se compara por valor para tipos primitivos e cadeias de caracteres). Um erro comum relacionado é escrever acidentalmente = (atribuição) quando você queria usar == (teste de igualdade). O compilador captura os formulários mais comuns, mas verifica novamente qualquer if condição que contenha =.
Operadores lógicos condicionais
&& (AND) e || (OR) combinam bool expressões.
int age = 20;
bool hasTicket = true;
// && (AND): both sides must be true
bool canEnter = age >= 18 && hasTicket;
Console.WriteLine(canEnter); // => True
// || (OR): at least one side must be true
bool freeEntry = age < 5 || age >= 65;
Console.WriteLine(freeEntry); // => False
// Short-circuit: right side is skipped when the result is already determined
// Here, items.Count is never called if items is null
List<string>? items = null;
bool hasItems = items != null && items.Count > 0;
Console.WriteLine(hasItems); // => False (short-circuits; no NullReferenceException)
Ambos os operadores de curto-circuito: eles ignoram a avaliação do operando certo quando o resultado já está determinado.
-
&&retornafalseassim que o lado esquerdo éfalse. O lado direito nunca é avaliado. -
||retornatrueassim que o lado esquerdo étrue. O lado direito nunca é avaliado.
O comportamento de curto-circuito tem um benefício prático: você pode proteger com segurança uma operação no lado direito com uma verificação nula no lado esquerdo, como mostra o exemplo acima. Se items é null, o && para ali — items.Count nunca é chamado, então nenhum NullReferenceException é lançado.
Operador condicional ?:
O operador condicional (também chamado de operador ternário ) avalia uma das duas expressões com base em uma condição:
condition ? value-when-true : value-when-false
int temperature2 = 35;
// condition ? value-when-true : value-when-false
string weather = temperature2 > 30 ? "hot" : "comfortable";
Console.WriteLine(weather); // => hot
// Only the matching branch evaluates — the other branch is never run
int divisor = 0;
// The division 10 / divisor is never evaluated because divisor == 0 is true
int safe = divisor == 0 ? -1 : 10 / divisor;
Console.WriteLine(safe); // => -1
O operador ?: sempre avalia exatamente um ramo — o ramo que não corresponde à condição nunca é avaliado. Isso torna seguro usar uma expressão de um lado que falharia em outras entradas, desde que a condição a protege corretamente.
Use ?: para opções simples, em linha. Para condições de várias vias ou blocos de código, uma instrução if/else geralmente é mais clara.
Operadores de atribuição
O operador = de atribuição simples armazena um valor em uma variável:
int level = 1; // declaration + initialization
level = 5; // reassignment
A atribuição em C# é associativa à direita, o que significa que a = b = c = 0 é avaliada da direita para a esquerda: c recebe 0, depois b recebe 0, e em seguida a recebe 0.
Atribuição composta
Operadores de atribuição composta combinam uma operação binária com atribuição:
| Operador | Equivalente a |
|---|---|
x += y |
x = x + y |
x -= y |
x = x - y |
x *= y |
x = x * y |
x /= y |
x = x / y |
x %= y |
x = x % y |
int level = 1;
level = 5; // simple assignment: replaces the value
Console.WriteLine(level); // => 5
// Compound assignment: short form of binary operation + assignment
int hp = 100;
hp += 20; // same as: hp = hp + 20
Console.WriteLine(hp); // => 120
hp -= 10; // same as: hp = hp - 10
Console.WriteLine(hp); // => 110
hp *= 2; // same as: hp = hp * 2
Console.WriteLine(hp); // => 220
hp /= 3; // same as: hp = hp / 3 (integer division)
Console.WriteLine(hp); // => 73
hp %= 7; // same as: hp = hp % 7
Console.WriteLine(hp); // => 3
A atribuição composta é mais do que apenas uma abreviação. Ele avalia o lado esquerdo exatamente uma vez e depois converte o resultado de volta para o tipo do lado esquerdo. Isso importa quando o lado esquerdo tem efeitos colaterais (como um indexador de array), e é por isso que a atribuição composta em uma variável byte compila sem uma conversão explícita, enquanto a forma expandida não:
// Assignment is right-associative: evaluated right to left
int a2, b2, c2;
a2 = b2 = c2 = 0; // c2 = 0 first, then b2 = 0, then a2 = 0
Console.WriteLine($"{a2} {b2} {c2}"); // => 0 0 0
// Compound assignment evaluates the left side once and converts back to the LHS type
byte small = 200;
small += 10; // equivalent to: small = (byte)(small + 10); result is 210
Console.WriteLine(small); // => 210
small += 10 compila porque o compilador insere a conversão de estreitamento automaticamente — o resultado, 210se encaixa dentro do byte intervalo de 0 a 255.
small = small + 10 exigiria uma conversão explícita para (byte), porque a aritmética promove ambos os operandos para int.
Outros operadores C#
Este artigo aborda os operadores que você mais encontrará no código cotidiano. A linguagem C# inclui mais operadores úteis em cenários específicos:
-
Operadores shift (
<<,>>,>>>) – deslocam os bits de um valor inteiro para a esquerda ou direita por um número especificado de posições. Operadores bit a bit e lógicos inteiros (&,|,^,~) — combinam ou invertem valores inteiros, um bit de cada vez, úteis em flags, máscaras e código de baixo nível: Operadores bit a bit e de deslocamento -
checkedeunchecked— controlar se o estouro de inteiro gera uma exceção (checked) ou encapsula silenciosamente (unchecked): marcado e desmarcado -
Operadores nulos (
??,??=,?[],?.) — lidam com segurança com valoresnullfornecendo valores padrão ou aplicando curto-circuito ao acesso a membros: Operadores nulos -
Operadores de teste de tipo e conversão (
is,as,typeof, coerção(T)) — verificam ou convertem o tipo de um valor em tempo de execução: Operadores de teste de tipo e coerção -
Operadores de intervalo e índice (
..,^) – criar intervalos e índices relativos ao final para fatiar matrizes e intervalos: acesso a membros e operadores condicionais nulos - Atribuição de desconstrução – desempacotar uma tupla ou tipo em variáveis individuais em uma única expressão: desconstruindo tuplas e outros tipos
Consulte também
- Expressões C# — como as expressões se formam e como funciona a precedência do operador
-
Comparações de igualdade — como
==,!=eEqualsfuncionam em diferentes tipos - Operadores e expressões C# (referência de linguagem) — tabela de precedência completa e todos os operadores