Operatori Unity C# indispensabili

Unity è un motore di gioco che fa un sacco di "heavy-lifting" per gli sviluppatori in termini di funzionalità e consente loro di concentrarsi interamente sul processo di sviluppo. Utilizza C# come linguaggio di programmazione principale.

Come qualsiasi linguaggio di programmazione, C# è costituito da una serie di funzioni speciali, tipi, classi, librerie, ecc., ma ha anche un elenco di simboli speciali (operatori) ognuno dei quali ha la sua funzione. In questo post, elencherò tali simboli e spiegherò cosa fanno, in modo che la prossima volta che aprirai uno script, sarai in grado di capire rapidamente cosa significa ogni parte.

Gli operatori in C# sono simboli speciali che eseguono determinate azioni sugli operandi.

In C#, ci sono 6 tipi di operatori incorporati: operatori aritmetici, operatori di confronto, operatori logici booleani, operatori bitwise e shift, operatori di uguaglianza e operatori vari. Conoscerli tutti ti renderà immediatamente un programmatore migliore.

1. Operatori aritmetici

I seguenti operatori eseguono operazioni aritmetiche con operandi di tipo numerico:

  • Operatori unari ++ (incremento), -- (decremento), + (più) e - (meno)
  • Operatori binari * (moltiplicazione), / (divisione), % (resto), + (addizione) e - (sottrazione)

Operatore di incremento ++

L'operatore "add one" (o ++) significa += 1, in altre parole, è un modo rapido per aggiungere un intero a un valore numerico, senza dover digitare codice extra. Questo operatore può essere aggiunto prima o dopo il valore, il che comporterebbe un comportamento diverso:

//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

Operatore di decremento --

L'operatore "subtract one" è l'opposto di ++ (-= 1), il che significa che sottrae un intero da un valore numerico. Può anche essere aggiunto prima o dopo un valore:

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

Operatori unari + e -

L'operatore unario + restituisce il valore del suo operando, mentre l'operatore unario - calcola la negazione numerica del suo 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

Operatore di moltiplicazione *

L'operatore di moltiplicazione * calcola il prodotto moltiplicato dei suoi operandi:

Debug.Log(6 * 3);         // output: 18
Debug.Log(1.5 * 3.5);     // output: 5.25
Debug.Log(0.1m * 24.4m);  // output: 2.44

Operatore di divisione /

L'operatore di divisione / divide il suo operando di sinistra per quello di destra.

Se uno degli operandi è decimale, un altro operando non può essere né float né double, perché né float né double sono convertibili implicitamente in decimale. Devi convertire esplicitamente l'operando float o double nel tipo decimale.

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

Operatore di resto %

L'operatore resto % calcola il resto dopo aver diviso il suo operando di sinistra per quello di destra.

  • Per gli operandi di tipo intero, il risultato di a % b è il valore prodotto da 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
  • Per gli operandi decimali, l'operatore resto % è equivalente all'operatore resto del 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

Operatore di addizione +

L'operatore di addizione + calcola la somma dei suoi operandi. Puoi anche usare l'operatore + per la concatenazione di stringhe e la combinazione di delegati.

Debug.Log(6 + 5);       // output: 11
Debug.Log(6 + 5.3);     // output: 11.3
Debug.Log(6.1m + 5.2m); // output: 11.3

Operatore di sottrazione -

L'operatore di sottrazione - sottrae il suo operando di destra dal suo operando di sinistra. Puoi anche usare l'operatore - per la rimozione dei delegati.

Debug.Log(48 - 4);      // output: 44
Debug.Log(6 - 5.3);     // output: 0.7
Debug.Log(8.5m - 3.3m); // output: 5.2

2. Operatori di confronto

Gli operatori di confronto < (less than), > (greater than), <= (less than or equal), and >= (maggiore o uguale), noti anche come relazionali, confrontano i loro operandi. Tali operatori sono supportati da tutti i tipi numerici integrali e in virgola mobile.

Operatore minore di <

L'operatore < restituisce true se il suo operando di sinistra è minore del suo operando di destra, false in caso contrario.

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

Operatore maggiore di >

L'operatore > restituisce true se il suo operando di sinistra è maggiore del suo operando di destra, false in caso contrario.

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

Operatore minore o uguale <=

L'operatore <= restituisce true se il suo operando di sinistra è minore o uguale al suo operando di destra, false in caso contrario.

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

Operatore maggiore o uguale >=

L'operatore >= restituisce true se il suo operando di sinistra è maggiore o uguale al suo operando di destra, false in caso contrario.

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. Operatori logici booleani

I seguenti operatori eseguono operazioni logiche con operandi booleani:

  • Operatore unario ! (negazione logica).
  • Operatori binari & (AND logico), | (OR logico) e ^ (OR logico esclusivo). Tali operatori valutano sempre entrambi gli operandi.
  • Operatori binari && (AND logico condizionale) e || (OR logico condizionale). Questi operatori valutano l'operando di destra solo se necessario.

Operatore di negazione logica !

L'operatore prefisso unario ! calcola la negazione logica del suo operando. Vale a dire, produce true, se l'operando valuta false, e false, se l'operando valuta true.

bool passed = false;
Debug.Log(!passed);  // output: True
Debug.Log(!true);    // output: False

Operatore logico AND &

L'operatore & calcola l'AND logico dei suoi operandi. Il risultato di x & y è vero se sia x che y sono valutati come veri. Altrimenti, il risultato è falso.

L'operatore & valuta entrambi gli operandi anche se l'operando di sinistra è valutato come falso, in modo che il risultato dell'operazione sia falso indipendentemente dal valore dell'operando di destra.

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

Operatore logico OR esclusivo ^

L'operatore ^ calcola l'OR logico esclusivo, noto anche come XOR logico, dei suoi operandi. Il risultato di x ^ y è vero se x viene valutato come vero e y viene valutato come falso, oppure x viene valutato come falso e y viene valutato come vero. Altrimenti, il risultato è falso. Vale a dire, per gli operandi bool, l'operatore ^ calcola lo stesso risultato dell'operatore di disuguaglianza !=.

Debug.Log(true ^ true);    // output: False
Debug.Log(true ^ false);   // output: True
Debug.Log(false ^ true);   // output: True
Debug.Log(false ^ false);  // output: False

Operatore logico OR |

L'operatore | calcola l'OR logico dei suoi operandi. Il risultato di x | y è vero se x o y sono valutati come veri, altrimenti il ​​risultato è falso.

L'operatore | valuta entrambi gli operandi anche se l'operando di sinistra è valutato come vero, in modo che il risultato dell'operazione sia vero indipendentemente dal valore dell'operando di destra.

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

Operatore logico AND condizionale &&

L'operatore logico AND condizionale &&, noto anche come operatore logico AND "short-circuiting", calcola l'AND logico dei suoi operandi. Il risultato di x && y è vero se sia x che y vengono valutati come veri, altrimenti il ​​risultato è falso. Se x viene valutato come falso, y non viene valutato.

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

Operatore logico OR condizionale ||

L'operatore logico OR condizionale ||, noto anche come operatore logico OR "short-circuiting", calcola l'OR logico dei suoi operandi. Il risultato di x || y è vero se x o y vengono valutati come veri. Altrimenti, il risultato è falso. Se x viene valutato come vero, y non viene valutato.

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. Operatori bit a bit e di spostamento

I seguenti operatori eseguono operazioni bit a bit o di spostamento con operandi di tipo numerico integrale o di tipo char:

  • Operatore unario ~ (complemento bit a bit)
  • Operatori di spostamento binari << (left shift) and >> (spostamento a destra)
  • Operatori binari & (AND logico), | (OR logico) e ^ (OR logico esclusivo)

Operatore di complemento bit a bit ~

L'operatore ~ ​​produce un complemento bit a bit del suo operando invertendo ogni bit.

uint a = 0b_0000_1111_0000_1111_0000_1111_0000_1100;
uint b = ~a;
Debug.Log(Convert.ToString(b, toBase: 2));
// Output:
// 11110000111100001111000011110011

Operatore di spostamento a sinistra <<

L'operatore << sposta il suo operando di sinistra a sinistra del numero di bit definiti dal suo operando di destra. Per informazioni su come l'operando di destra definisce il conteggio degli spostamenti, vedere la sezione Conteggio degli spostamenti degli operatori di spostamento.

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

Operatore di spostamento a destra >>

L'operatore >> sposta il suo operando di sinistra verso destra del numero di bit definiti dal suo operando di destra.

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

Le posizioni dei bit vuoti di ordine superiore vengono impostate in base al tipo dell'operando di sinistra come segue:

  • Se l'operando di sinistra è di tipo int o long, l'operatore di spostamento a destra esegue uno spostamento aritmetico: il valore del bit più significativo (il bit di segno) dell'operando di sinistra viene propagato alle posizioni di bit vuoti di ordine superiore. Vale a dire, le posizioni di bit vuoti di ordine superiore vengono impostate a zero se l'operando di sinistra è non negativo e impostate a uno se è 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 l'operando di sinistra è di tipo uint o ulong, l'operatore di spostamento a destra esegue uno spostamento logico: le posizioni dei bit vuoti di ordine superiore vengono sempre impostate su 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

Operatore logico AND &

L'operatore & calcola l'AND logico bit a bit dei suoi operandi integrali.

uint a = 0b_1111_1000;
uint b = 0b_1001_1101;
uint c = a & b;
Debug.Log(Convert.ToString(c, toBase: 2));
// Output:
// 10011000

Operatore logico OR esclusivo ^

L'operatore ^ calcola l'OR logico esclusivo bit a bit, noto anche come XOR logico bit a bit, dei suoi operandi integrali.

uint a = 0b_1111_1000;
uint b = 0b_0001_1100;
uint c = a ^ b;
Debug.Log(Convert.ToString(c, toBase: 2));
// Output:
// 11100100

Operatore logico OR |

L'operatore | calcola l'OR logico bit a bit dei suoi operandi integrali.

uint a = 0b_1010_0000;
uint b = 0b_1001_0001;
uint c = a | b;
Debug.Log(Convert.ToString(c, toBase: 2));
// Output:
// 10110001

5. Operatori di uguaglianza

Gli operatori == (uguaglianza) e != (disuguaglianza) verificano se i loro operandi sono uguali o meno.

Operatore di uguaglianza ==

L'operatore di uguaglianza == restituisce true se i suoi operandi sono uguali, false altrimenti.

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

Operatore di disuguaglianza !=

L'operatore di disuguaglianza != restituisce true se i suoi operandi non sono uguali, false altrimenti. Per gli operandi dei tipi incorporati, l'espressione x != y produce lo stesso risultato dell'espressione !(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. Operatori vari

Gli operatori vari più comuni sono ?: per i controlli condizionali, :: per accedere a un membro di uno spazio dei nomi con alias e $ per l'interpolazione di stringhe.

?: operatore

L'operatore condizionale ?:, noto anche come operatore condizionale ternario, valuta un'espressione booleana e restituisce il risultato di una delle due espressioni, a seconda che l'espressione booleana venga valutata come vera o falsa, come mostra il seguente esempio:

bool condition = true;
Debug.Log(condition ? 1 : 2); // output: 1

:: operatore

Utilizzare il qualificatore alias namespace:: per accedere a un membro di un namespace con alias. È possibile utilizzare il qualificatore:: solo tra due identificatori. L'identificatore di sinistra può essere uno qualsiasi dei seguenti alias:

  • Un alias dello spazio dei nomi creato con una direttiva 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);
}
  • Un alias esterno.
  • L'alias globale, che è l'alias dello spazio dei nomi globale. Lo spazio dei nomi globale è lo spazio dei nomi che contiene spazi dei nomi e tipi che non sono dichiarati all'interno di uno spazio dei nomi denominato. Quando utilizzato con il qualificatore::, l'alias globale fa sempre riferimento allo spazio dei nomi globale, anche se è presente l'alias dello spazio dei nomi globale definito dall'utente.
namespace MyCompany.MyProduct.System
{
    class Program
    {
        static void Main() => global::System.Console.WriteLine("Using global alias");
    }

    class Console
    {
        string Suggestion => "Consider renaming this class";
    }
}

$ operatore

Il carattere speciale $ identifica una stringa letterale come stringa interpolata. Una stringa interpolata è una stringa letterale che potrebbe contenere espressioni di interpolazione. Quando una stringa interpolata viene risolta in una stringa di risultato, gli elementi con espressioni di interpolazione vengono sostituiti dalle rappresentazioni di stringa dei risultati dell'espressione.

In Interpolated Strings, il simbolo del dollaro ($) viene utilizzato per indicare al compilatore C# che la stringa che lo segue deve essere interpretata come una Interpolated String. Le parentesi graffe incapsulano i valori (delle variabili) da includere nel testo.

Per identificare una stringa letterale come stringa interpolata, anteponi il simbolo $. Non puoi avere spazi vuoti tra $ e " che iniziano una stringa letterale.

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.