Operatory Unity C#, które trzeba znać

Unity to silnik gry, który wykonuje wiele "heavy-lifting" dla programistów pod względem funkcjonalności i pozwala im całkowicie skupić się na procesie tworzenia. Wykorzystuje C# jako główny język programowania.

Podobnie jak każdy język programowania, C# składa się z szeregu specjalnych funkcji, typów, klas, bibliotek itp., ale zawiera także listę specjalnych symboli (operatorów), z których każdy ma swoją własną funkcję. W tym poście wymienię te symbole i wyjaśnię, co robią, dzięki czemu następnym razem, gdy otworzysz skrypt, będziesz mógł szybko zrozumieć, co oznacza każda część.

Operatory w języku C# to specjalne symbole, które wykonują pewne akcje na operandach.

W C# istnieje 6 typów wbudowanych operatorów: operatory arytmetyczne, operatory porównania, operatory logiczne Boole'a, operatory bitowe i przesunięcia, operatory równości i operatory różne. Znajomość ich wszystkich sprawi, że od razu staniesz się lepszym programistą.

1. Operatory arytmetyczne

Następujące operatory wykonują operacje arytmetyczne na argumentach typów numerycznych:

  • Jednoargumentowe operatory ++ (zwiększanie), -- (zmniejszanie), + (plus) i - (minus).
  • Binarne operatory * (mnożenie), / (dzielenie), % (reszta), + (dodawanie) i - (odejmowanie)

Operator inkrementacji++

Operator "add one" (lub ++) oznacza += 1, innymi słowy, jest to szybki sposób na dodanie jednej liczby całkowitej do wartości numerycznej bez konieczności wpisywania dodatkowego kodu. Operator ten można dodać przed wartością lub po wartości, co spowoduje inne zachowanie:

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

Operator zmniejszania --

Operator "subtract one" jest przeciwieństwem ++ (-= 1), co oznacza, że ​​odejmuje jedną liczbę całkowitą od wartości liczbowej. Można go również dodać przed lub po wartości:

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

Jednoargumentowe operatory + i -

Operator jednoargumentowy + zwraca wartość swojego operandu, a operator jednoargumentowy - oblicza numeryczną negację swojego operandu.

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

Operator mnożenia *

Operator mnożenia * oblicza iloczyn swoich operandów:

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

Operator podziału /

Operator dzielenia / dzieli swój lewy operand przez prawy operand.

Jeśli jeden z operandów jest dziesiętny, inny operand nie może być ani zmiennoprzecinkowy, ani double, ponieważ ani float, ani double nie można w sposób dorozumiany konwertować na dziesiętny. Należy jawnie przekonwertować operand zmiennoprzecinkowy lub podwójny na typ dziesiętny.

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

Pozostały operator%

Operator reszty % oblicza resztę po podzieleniu lewego operandu przez prawy operand.

  • Dla operandów typów całkowitych wynik a % b jest wartością wygenerowaną przez 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
  • W przypadku operandów dziesiętnych operator reszty % jest równoważny operatorowi reszty typu 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

Operator dodawania +

Operator dodawania + oblicza sumę swoich operandów. Możesz także użyć operatora + do łączenia ciągów i kombinacji delegatów.

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

Operator odejmowania -

Operator odejmowania - odejmuje swój prawy operand od lewego operandu. Możesz także użyć operatora - do usunięcia delegata.

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

2. Operatory porównania

Operatory < (less than), > (greater than), <= (less than or equal), and >= (większe lub równe), zwane także relacyjnymi, służą do porównywania swoich operandów. Operatory te są obsługiwane przez wszystkie całkowe i zmiennoprzecinkowe typy liczbowe.

Mniej niż operator <

Operator < zwraca wartość true, jeśli jego lewy operand jest mniejszy niż prawy operand, w przeciwnym razie false.

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

Większy niż operator >

Operator > zwraca wartość true, jeśli jego lewy operand jest większy niż prawy operand, w przeciwnym razie false.

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

Operator mniejszy lub równy <=

Operator <= zwraca wartość true, jeśli jego lewy operand jest mniejszy lub równy jego prawemu operandowi, w przeciwnym razie false.

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

Operator większy lub równy >=

Operator >= zwraca wartość true, jeśli jego lewy operand jest większy lub równy jego prawemu operandowi, w przeciwnym razie false.

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. Operatory logiczne logiczne

Następujące operatory wykonują operacje logiczne na operandach typu bool:

  • Jednoargumentowy! operator (negacji logicznej).
  • Binarny i (logiczny AND), | (logiczne OR) i ^ (logiczne wyłączne OR). Operatory te zawsze oceniają oba operandy.
  • Binarny && (warunkowe logiczne AND) i || (warunkowe logiczne OR). Operatory te oceniają operand po prawej stronie tylko wtedy, gdy jest to konieczne.

Logiczny operator negacji !

Przedrostek jednoargumentowy! operator oblicza logiczną negację swojego operandu. Oznacza to, że generuje wartość true, jeśli operand ma wartość false, i false, jeśli operand ma wartość true.

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

Operator logiczny AND &

Operator & oblicza logiczne AND swoich operandów. Wynik x i y jest prawdziwy, jeśli zarówno x, jak i y mają wartość true. W przeciwnym razie wynik będzie fałszywy.

Operator & oblicza oba operandy, nawet jeśli operand po lewej stronie ma wartość false, zatem wynik operacji będzie fałszywy niezależnie od wartości operandu po prawej stronie.

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

Logiczny wyłączny operator OR ^

Operator ^ oblicza logiczny OR, znany również jako logiczny XOR, swoich operandów. Wynik x ^ y jest prawdziwy, jeśli x ma wartość true, a y ma wartość false, lub x ma wartość false, a y ma wartość true. W przeciwnym razie wynik będzie fałszywy. Oznacza to, że w przypadku operandów typu bool operator ^ oblicza ten sam wynik, co operator nierówności !=.

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

Operator logiczny OR |

| operator oblicza logiczne OR swoich operandów. Wynik x | y jest prawdziwe, jeśli x lub y ma wartość true, w przeciwnym razie wynik jest fałszywy.

The | operator ocenia oba operandy, nawet jeśli lewy operand ma wartość true, zatem wynik operacji będzie prawdziwy niezależnie od wartości prawego operandu.

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

Warunkowy operator logiczny AND &&

Warunkowy operator logiczny AND &&, znany również jako operator logiczny AND "short-circuiting", oblicza logiczne AND swoich operandów. Wynik x && y jest prawdziwy, jeśli zarówno x, jak i y mają wartość true, w przeciwnym razie wynik jest fałszywy. Jeśli x ma wartość false, y nie jest oceniane.

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

Warunkowy operator logiczny OR ||

Warunkowy operator logiczny OR ||, znany również jako "short-circuiting" operator logiczny OR, oblicza logiczny OR swoich operandów. Wynik x || y jest prawdziwe, jeśli x lub y ma wartość true. W przeciwnym razie wynik będzie fałszywy. Jeśli x ma wartość true, y nie jest oceniane.

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. Operatory bitowe i przesunięcia

Następujące operatory wykonują operacje bitowe lub przesunięcia na operandach całkowitych typów liczbowych lub typu char:

  • Operator jednoargumentowy ~ (dopełnienie bitowe).
  • Operatory przesunięcia binarnego << (left shift) and >> (przesunięcie w prawo).
  • Binarny i (logiczny AND), | (logiczne OR) i ^ (logiczne wyłączne OR).

Operator dopełnienia bitowego ~

Operator ~ tworzy bitowe uzupełnienie swojego operandu poprzez odwrócenie każdego bitu.

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

Operator przesunięcia w lewo <<

Operator << przesuwa swój lewy operand w lewo o liczbę bitów zdefiniowaną przez jego prawy operand. Aby uzyskać informacje na temat sposobu, w jaki operand po prawej stronie definiuje liczbę przesunięć, zobacz sekcję Liczba przesunięć w operatorach przesunięcia.

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

Operator z prawym przesunięciem >>

Operator >> przesuwa swój lewy operand w prawo o liczbę bitów zdefiniowaną przez jego prawy operand.

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

Pozycje pustych bitów wyższego rzędu są ustawiane w oparciu o typ lewego operandu w następujący sposób:

  • Jeśli lewy operand jest typu int lub long, operator przesunięcia w prawo wykonuje przesunięcie arytmetyczne: wartość najbardziej znaczącego bitu (bitu znaku) lewego operandu jest propagowana do pustego bitu wyższego rzędu pozycje. Oznacza to, że puste pozycje bitów wyższego rzędu są ustawiane na zero, jeśli lewy operand jest nieujemny, i ustawiane na jeden, jeśli jest ujemny.
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
  • Jeżeli operand po lewej stronie jest typu uint lub ulong, operator przesunięcia w prawo wykonuje przesunięcie logiczne: pozycje pustych bitów wyższego rzędu są zawsze ustawiane na 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

Operator logiczny AND &

Operator & oblicza bitowe logiczne AND swoich całkowitych operandów.

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

Logiczny wyłączny operator OR ^

Operator ^ oblicza bitowe logiczne wyłączne OR, znane również jako bitowe logiczne XOR, swoich całkowitych operandów.

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

Operator logiczny OR |

| operator oblicza bitowe logiczne OR swoich całkowitych operandów.

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

5. Operatory równości

Operatory == (równość) i != (nierówność) sprawdzają, czy ich operandy są równe, czy nie.

Operator równości ==

Operator równości == zwraca wartość true, jeśli jego operandy są równe, w przeciwnym razie false.

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

Operator nierówności !=

Operator nierówności != zwraca wartość true, jeśli jego argumenty nie są równe, w przeciwnym razie wartość false. W przypadku operandów typów wbudowanych wyrażenie x != y daje taki sam wynik jak wyrażenie !(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. Różni operatorzy

Typowymi różnymi operatorami są ?: do kontroli warunkowych,:: do dostępu do elementu członkowskiego aliasowanej przestrzeni nazw i $ do interpolacji ciągów.

?: operator

Operator warunkowy ?:, znany również jako potrójny operator warunkowy, ocenia wyrażenie logiczne i zwraca wynik jednego z dwóch wyrażeń, w zależności od tego, czy wyrażenie logiczne ma wartość prawda, czy fałsz, jak pokazuje poniższy przykład:

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

:: operatora

Użyj kwalifikatora aliasu przestrzeni nazw::, aby uzyskać dostęp do elementu członkowskiego aliasowanej przestrzeni nazw. Kwalifikatora:: można używać tylko pomiędzy dwoma identyfikatorami. Identyfikatorem po lewej stronie może być dowolny z następujących aliasów:

  • Alias ​​przestrzeni nazw utworzony za pomocą dyrektywy 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);
}
  • Zewnętrzny pseudonim.
  • Alias ​​globalny, czyli alias globalnej przestrzeni nazw. Globalna przestrzeń nazw to przestrzeń nazw zawierająca przestrzenie nazw i typy, które nie są zadeklarowane w nazwanej przestrzeni nazw. W przypadku użycia z kwalifikatorem:: alias globalny zawsze odwołuje się do globalnej przestrzeni nazw, nawet jeśli istnieje alias globalnej przestrzeni nazw zdefiniowany przez użytkownika.
namespace MyCompany.MyProduct.System
{
    class Program
    {
        static void Main() => global::System.Console.WriteLine("Using global alias");
    }

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

operatora $

Znak specjalny $ identyfikuje literał ciągu jako ciąg interpolowany. Ciąg interpolowany to literał ciągu, który może zawierać wyrażenia interpolacyjne. Gdy interpolowany ciąg znaków jest przekształcany w ciąg wynikowy, elementy z wyrażeniami interpolacyjnymi są zastępowane ciągami reprezentującymi wyniki wyrażenia.

W ciągach interpolowanych znak dolara ($) służy do informowania kompilatora C#, że następujący po nim ciąg ma być interpretowany jako ciąg interpolowany. Nawiasy klamrowe hermetyzują wartości (zmiennych), które mają zostać uwzględnione w tekście.

Aby zidentyfikować literał ciągu jako ciąg interpolowany, należy go poprzedzić symbolem $. Nie może być spacji pomiędzy $ i " rozpoczynającym literał łańcuchowy.

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.
Sugerowane artykuły
Zrozumienie funkcji i wywołań metod
Wprowadzenie do języka skryptowego Unity C#
Implementacja podstawowych operacji arytmetycznych w kodzie Unity
Jak zostać lepszym programistą w Unity
Skrypt do chwytania obiektów w Unity
Metody na początku środowiska wykonawczego, które inicjują wartości w jedności
Kompilacja specyficzna dla platformy Unity