Operadores essenciais do Unity C#
Unity é um motor de jogo que faz muito "heavy-lifting" para desenvolvedores em termos de funcionalidade e permite que eles se concentrem inteiramente no processo de desenvolvimento. Ele utiliza C# como a linguagem de programação principal.
Assim como qualquer linguagem de programação, C# consiste em uma matriz de funções especiais, tipos, classes, bibliotecas, etc., mas também tem uma lista de símbolos especiais (operadores) que têm cada um sua própria função. Neste post, listarei esses símbolos e explicarei o que eles fazem, para que na próxima vez que você abrir um script, consiga entender rapidamente o que cada parte significa.
Operadores em C# são alguns símbolos especiais que executam alguma ação em operandos.
Em C#, há 6 tipos de operadores internos: operadores aritméticos, operadores de comparação, operadores lógicos booleanos, operadores bitwise e shift, operadores de igualdade e operadores diversos. Conhecer todos eles fará de você um programador melhor instantaneamente.
1. Operadores aritméticos
Os seguintes operadores realizam operações aritméticas com operandos de tipos numéricos:
- Operadores unários ++ (incremento), -- (decremento), + (mais) e - (menos)
- Operadores binários * (multiplicação), / (divisão), % (resto), + (adição) e - (subtração)
Operador de incremento ++
O operador "add one" (ou ++) significa += 1, em outras palavras, é uma maneira rápida de adicionar um inteiro a um valor numérico, sem precisar digitar código extra. Este operador pode ser adicionado antes ou depois do valor, o que resultaria em um comportamento diferente:
//The result of x++ is the value of x before the operation, as the following example shows:
int i = 4;
Debug.Log(i); // output: 4
Debug.Log(i++); // output: 4
Debug.Log(i); // output: 5
//The result of ++x is the value of x after the operation, as the following example shows:
double a = 2.5;
Debug.Log(a); // output: 2.5
Debug.Log(++a); // output: 3.5
Debug.Log(a); // output: 3.5
Operador de Decremento --
O operador "subtract one" é o oposto de ++ (-= 1), o que significa que ele subtrai um inteiro de um valor numérico. Ele também pode ser adicionado antes ou depois de um valor:
The result of x-- is the value of x before the operation, as the following example shows:
int i = 4;
Debug.Log(i); // output: 4
Debug.Log(i--); // output: 4
Debug.Log(i); // output: 3
The result of --x is the value of x after the operation, as the following example shows:
double a = 2.5;
Debug.Log(a); // output: 2.5
Debug.Log(--a); // output: 1.5
Debug.Log(a); // output: 1.5
Operadores unários + e -
O operador unário + retorna o valor do seu operando e o operador unário - calcula a negação numérica do seu operando.
Debug.Log(+5); // output: 5
Debug.Log(-5); // output: -5
Debug.Log(-(-5)); // output: 5
uint a = 6;
var b = -a;
Debug.Log(b); // output: -6
Debug.Log(b.GetType()); // output: System.Int64
Debug.Log(-double.NaN); // output: NaN
Operador de multiplicação *
O operador de multiplicação * calcula o produto multiplicado de seus operandos:
Debug.Log(6 * 3); // output: 18
Debug.Log(1.5 * 3.5); // output: 5.25
Debug.Log(0.1m * 24.4m); // output: 2.44
Operador de divisão /
O operador de divisão / divide seu operando esquerdo pelo seu operando direito.
Se um dos operandos for decimal, outro operando não pode ser float nem double, porque nem float nem double são implicitamente conversíveis para decimal. Você deve converter explicitamente o operando float ou double para o tipo decimal.
Debug.Log(13 / 5); // output: 2
Debug.Log(13 / 5.0); // output: 2.6
int a = 13;
int b = 5;
Debug.Log((double)a / b); // output: 2.6
Debug.Log(16.8f / 4.1f); // output: 4.097561
Debug.Log(16.8d / 4.1d); // output: 4.09756097560976
Debug.Log(16.8m / 4.1m); // output: 4.0975609756097560975609756098
Operador de resto %
O operador restante % calcula o restante após dividir seu operando esquerdo pelo seu operando direito.
- Para os operandos de tipos inteiros, o resultado de a % b é o valor produzido por a - (a / b) * b
Debug.Log(5 % 4); // output: 1
Debug.Log(5 % -4); // output: 1
Debug.Log(-5 % 4); // output: -1
Debug.Log(-5 % -4); // output: -1
- Para os operandos decimais, o operador de resto % é equivalente ao operador de resto do tipo System.Decimal.
Debug.Log(-5.2f % 2.0f); // output: -1.2
Debug.Log(5.9 % 3.1); // output: 2.8
Debug.Log(5.9m % 3.1m); // output: 2.8
Operador de adição +
O operador de adição + calcula a soma de seus operandos. Você também pode usar o operador + para concatenação de strings e combinação de delegados.
Debug.Log(6 + 5); // output: 11
Debug.Log(6 + 5.3); // output: 11.3
Debug.Log(6.1m + 5.2m); // output: 11.3
Operador de subtração -
O operador de subtração - subtrai seu operando direito de seu operando esquerdo. Você também pode usar o operador - para remoção de delegado.
Debug.Log(48 - 4); // output: 44
Debug.Log(6 - 5.3); // output: 0.7
Debug.Log(8.5m - 3.3m); // output: 5.2
2. Operadores de comparação
Os operadores de comparação < (less than), > (greater than), <= (less than or equal), and >= (maior que ou igual), também conhecidos como relacionais, comparam seus operandos. Esses operadores são suportados por todos os tipos numéricos integrais e de ponto flutuante.
Operador menor que <
O operador < retorna verdadeiro se seu operando esquerdo for menor que seu operando direito, falso caso contrário.
Debug.Log(8.0 < 6.1); // output: False
Debug.Log(6.1 < 6.1); // output: False
Debug.Log(1.0 < 6.1); // output: True
Debug.Log(double.NaN < 6.1); // output: False
Debug.Log(double.NaN >= 6.1); // output: False
Operador maior que >
O operador > retorna verdadeiro se seu operando esquerdo for maior que seu operando direito, falso caso contrário.
Debug.Log(8.0 > 6.1); // output: True
Debug.Log(6.1 > 6.1); // output: False
Debug.Log(1.0 > 6.1); // output: False
Debug.Log(double.NaN > 6.1); // output: False
Debug.Log(double.NaN <= 6.1); // output: False
Operador menor ou igual <=
O operador <= retorna verdadeiro se seu operando esquerdo for menor ou igual ao seu operando direito, falso caso contrário.
Debug.Log(8.0 <= 6.1); // output: False
Debug.Log(6.1 <= 6.1); // output: True
Debug.Log(1.0 <= 6.1); // output: True
Debug.Log(double.NaN > 6.1); // output: False
Debug.Log(double.NaN <= 6.1); // output: False
Operador maior ou igual >=
O operador >= retorna verdadeiro se seu operando esquerdo for maior ou igual ao seu operando direito, falso caso contrário.
Debug.Log(8.0 >= 6.1); // output: True
Debug.Log(6.1 >= 6.1); // output: True
Debug.Log(1.0 >= 6.1); // output: False
Debug.Log(double.NaN < 6.1); // output: False
Debug.Log(double.NaN >= 6.1); // output: False
3. Operadores lógicos booleanos
Os seguintes operadores executam operações lógicas com operandos bool:
- Operador unário ! (negação lógica).
- Operadores binários & (E lógico), | (OU lógico) e ^ (OU exclusivo lógico). Esses operadores sempre avaliam ambos os operandos.
- Operadores binários && (E lógico condicional) e || (OR lógico condicional). Esses operadores avaliam o operando do lado direito somente se for necessário.
Operador de negação lógico !
O operador de prefixo unário ! computa a negação lógica de seu operando. Ou seja, ele produz true, se o operando for avaliado como false, e false, se o operando for avaliado como true.
bool passed = false;
Debug.Log(!passed); // output: True
Debug.Log(!true); // output: False
Operador lógico AND &
O operador & calcula o AND lógico de seus operandos. O resultado de x & y é verdadeiro se ambos x e y forem avaliados como verdadeiros. Caso contrário, o resultado é falso.
O operador & avalia ambos os operandos mesmo se o operando da esquerda for avaliado como falso, de modo que o resultado da operação é falso independentemente do valor do operando da direita.
bool SecondOperand()
{
Debug.Log("Second operand is evaluated.");
return true;
}
bool a = false & SecondOperand();
Debug.Log(a);
// Output:
// Second operand is evaluated.
// False
bool b = true & SecondOperand();
Debug.Log(b);
// Output:
// Second operand is evaluated.
// True
Operador lógico exclusivo OR ^
O operador ^ calcula o OR exclusivo lógico, também conhecido como XOR lógico, de seus operandos. O resultado de x ^ y é verdadeiro se x for avaliado como verdadeiro e y for avaliado como falso, ou x for avaliado como falso e y for avaliado como verdadeiro. Caso contrário, o resultado é falso. Ou seja, para os operandos bool, o operador ^ calcula o mesmo resultado que o operador de desigualdade !=.
Debug.Log(true ^ true); // output: False
Debug.Log(true ^ false); // output: True
Debug.Log(false ^ true); // output: True
Debug.Log(false ^ false); // output: False
Operador lógico OR |
O operador | calcula o OR lógico de seus operandos. O resultado de x | y é verdadeiro se x ou y for avaliado como verdadeiro, caso contrário, o resultado é falso.
O operador | avalia ambos os operandos, mesmo se o operando da esquerda for avaliado como verdadeiro, de modo que o resultado da operação é verdadeiro, independentemente do valor do operando da direita.
bool SecondOperand()
{
Debug.Log("Second operand is evaluated.");
return true;
}
bool a = true | SecondOperand();
Debug.Log(a);
// Output:
// Second operand is evaluated.
// True
bool b = false | SecondOperand();
Debug.Log(b);
// Output:
// Second operand is evaluated.
// True
Operador lógico condicional AND &&
O operador lógico condicional AND &&, também conhecido como operador lógico AND "short-circuiting", calcula o AND lógico de seus operandos. O resultado de x && y é verdadeiro se x e y forem avaliados como verdadeiros, caso contrário, o resultado é falso. Se x for avaliado como falso, y não será avaliado.
bool SecondOperand()
{
Debug.Log("Second operand is evaluated.");
return true;
}
bool a = false && SecondOperand();
Debug.Log(a);
// Output:
// False
bool b = true && SecondOperand();
Debug.Log(b);
// Output:
// Second operand is evaluated.
// True
Operador lógico condicional OR ||
O operador lógico condicional OR ||, também conhecido como operador lógico OR "short-circuiting", calcula o OR lógico de seus operandos. O resultado de x || y é verdadeiro se x ou y for avaliado como verdadeiro. Caso contrário, o resultado é falso. Se x for avaliado como verdadeiro, y não é avaliado.
bool SecondOperand()
{
Debug.Log("Second operand is evaluated.");
return true;
}
bool a = true || SecondOperand();
Debug.Log(a);
// Output:
// True
bool b = false || SecondOperand();
Debug.Log(b);
// Output:
// Second operand is evaluated.
// True
4. Operadores bit a bit e de deslocamento
Os seguintes operadores realizam operações bit a bit ou de deslocamento com operandos dos tipos numéricos integrais ou do tipo char:
- Operador unário ~ (complemento bit a bit)
- Operadores de deslocamento binários << (left shift) and >> (deslocamento à direita)
- Operadores binários & (E lógico), | (OU lógico) e ^ (OU exclusivo lógico)
Operador de complemento bit a bit ~
O operador ~ produz um complemento bit a bit de seu operando invertendo cada bit.
uint a = 0b_0000_1111_0000_1111_0000_1111_0000_1100;
uint b = ~a;
Debug.Log(Convert.ToString(b, toBase: 2));
// Output:
// 11110000111100001111000011110011
Operador de deslocamento para a esquerda <<
O operador << desloca seu operando esquerdo para a esquerda pelo número de bits definido por seu operando direito. Para obter informações sobre como o operando direito define a contagem de deslocamento, consulte a seção Contagem de deslocamento dos operadores de deslocamento.
uint x = 0b_1100_1001_0000_0000_0000_0000_0001_0001;
Debug.Log($"Before: {Convert.ToString(x, toBase: 2)}");
uint y = x << 4;
Debug.Log($"After: {Convert.ToString(y, toBase: 2)}");
// Output:
// Before: 11001001000000000000000000010001
// After: 10010000000000000000000100010000
Operador de deslocamento para a direita >>
O operador >> desloca seu operando esquerdo para a direita pelo número de bits definido por seu operando direito.
uint x = 0b_1001;
Debug.Log($"Before: {Convert.ToString(x, toBase: 2), 4}");
uint y = x >> 2;
Debug.Log($"After: {Convert.ToString(y, toBase: 2), 4}");
// Output:
// Before: 1001
// After: 10
As posições de bits vazios de ordem superior são definidas com base no tipo do operando esquerdo da seguinte forma:
- Se o operando da esquerda for do tipo int ou long, o operador right-shift realiza um deslocamento aritmético: o valor do bit mais significativo (o bit de sinal) do operando da esquerda é propagado para as posições de bit vazio de ordem alta. Ou seja, as posições de bit vazio de ordem alta são definidas como zero se o operando da esquerda for não negativo e definidas como um se for negativo.
int a = int.MinValue;
Debug.Log($"Before: {Convert.ToString(a, toBase: 2)}");
int b = a >> 3;
Debug.Log($"After: {Convert.ToString(b, toBase: 2)}");
// Output:
// Before: 10000000000000000000000000000000
// After: 11110000000000000000000000000000
- Se o operando da esquerda for do tipo uint ou ulong, o operador de deslocamento para a direita executa um deslocamento lógico: as posições de bits vazios de ordem superior são sempre definidas como zero.
uint c = 0b_1000_0000_0000_0000_0000_0000_0000_0000;
Debug.Log($"Before: {Convert.ToString(c, toBase: 2), 32}");
uint d = c >> 3;
Debug.Log($"After: {Convert.ToString(d, toBase: 2), 32}");
// Output:
// Before: 10000000000000000000000000000000
// After: 10000000000000000000000000000
Operador lógico AND &
O operador & calcula o AND lógico bit a bit de seus operandos integrais.
uint a = 0b_1111_1000;
uint b = 0b_1001_1101;
uint c = a & b;
Debug.Log(Convert.ToString(c, toBase: 2));
// Output:
// 10011000
Operador lógico exclusivo OR ^
O operador ^ calcula o OR exclusivo lógico bit a bit, também conhecido como XOR lógico bit a bit, de seus operandos integrais.
uint a = 0b_1111_1000;
uint b = 0b_0001_1100;
uint c = a ^ b;
Debug.Log(Convert.ToString(c, toBase: 2));
// Output:
// 11100100
Operador lógico OR |
O operador | calcula o OR lógico bit a bit de seus operandos integrais.
uint a = 0b_1010_0000;
uint b = 0b_1001_0001;
uint c = a | b;
Debug.Log(Convert.ToString(c, toBase: 2));
// Output:
// 10110001
5. Operadores de igualdade
Os operadores == (igualdade) e != (desigualdade) verificam se seus operandos são iguais ou não.
Operador de igualdade ==
O operador de igualdade == retorna verdadeiro se seus operandos são iguais, falso caso contrário.
int a = 1 + 2 + 3;
int b = 6;
Debug.Log(a == b); // output: True
char c1 = 'a';
char c2 = 'A';
Debug.Log(c1 == c2); // output: False
Debug.Log(c1 == char.ToLower(c2)); // output: True
Operador de desigualdade !=
O operador de desigualdade != retorna true se seus operandos não forem iguais, false caso contrário. Para os operandos dos tipos internos, a expressão x != y produz o mesmo resultado que a expressão !(x == y).
int a = 1 + 1 + 2 + 3;
int b = 6;
Debug.Log(a != b); // output: True
string s1 = "Hello";
string s2 = "Hello";
Debug.Log(s1 != s2); // output: False
object o1 = 2;
object o2 = 2;
Debug.Log(o1 != o2); // output: True
6. Operadores diversos
Operadores diversos comuns são ?: para verificações condicionais, :: para acessar um membro de um namespace com alias e $ para interpolação de strings.
?: operador
O operador condicional ?:, também conhecido como operador condicional ternário, avalia uma expressão booleana e retorna o resultado de uma das duas expressões, dependendo se a expressão booleana é avaliada como verdadeira ou falsa, como mostra o exemplo a seguir:
bool condition = true;
Debug.Log(condition ? 1 : 2); // output: 1
:: operador
Use o qualificador de alias de namespace:: para acessar um membro de um namespace com alias. Você pode usar o qualificador:: somente entre dois identificadores. O identificador do lado esquerdo pode ser qualquer um dos seguintes aliases:
- Um alias de namespace criado com uma diretiva using alias:
using forwinforms = System.Drawing;
using forwpf = System.Windows;
public class Converters
{
public static forwpf::Point Convert(forwinforms::Point point) => new forwpf::Point(point.X, point.Y);
}
- Um alias externo.
- O alias global, que é o alias do namespace global. O namespace global é o namespace que contém namespaces e tipos que não são declarados dentro de um namespace nomeado. Quando usado com o qualificador::, o alias global sempre faz referência ao namespace global, mesmo se houver o alias do namespace global definido pelo usuário.
namespace MyCompany.MyProduct.System
{
class Program
{
static void Main() => global::System.Console.WriteLine("Using global alias");
}
class Console
{
string Suggestion => "Consider renaming this class";
}
}
$ operador
O caractere especial $ identifica uma literal de string como uma string interpolada. Uma string interpolada é uma literal de string que pode conter expressões de interpolação. Quando uma string interpolada é resolvida para uma string de resultado, os itens com expressões de interpolação são substituídos pelas representações de string dos resultados da expressão.
Em Interpolated Strings, o cifrão ($) é usado para dizer ao compilador C# que a string que o segue deve ser interpretada como uma Interpolated String. As chaves encapsulam os valores (das variáveis) a serem incluídos no texto.
Para identificar uma literal de string como uma string interpolada, coloque o símbolo $ antes dela. Você não pode ter nenhum espaço em branco entre o $ e o " que inicia uma literal de string.
string name = "John";
var date = DateTime.Now;
Debug.Log($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");
// Output:
// Hello, John! Today is Wednesday, it's 19:40 now.