Các toán tử cần biết trong Unity C#

Unity là một công cụ trò chơi thực hiện rất nhiều "heavy-lifting" cho các nhà phát triển về mặt chức năng và cho phép họ tập trung hoàn toàn vào quá trình phát triển. Nó sử dụng C# làm ngôn ngữ lập trình chính.

Giống như bất kỳ ngôn ngữ lập trình nào, C# bao gồm một loạt các hàm, kiểu, lớp, thư viện đặc biệt, v.v., nhưng nó cũng có một danh sách các ký hiệu (toán tử) đặc biệt mà mỗi ký hiệu có chức năng riêng. Trong bài đăng này, tôi sẽ liệt kê các ký hiệu đó và giải thích chức năng của chúng để lần sau khi mở tập lệnh, bạn có thể nhanh chóng hiểu ý nghĩa của từng phần.

Toán tử trong C# là một số ký hiệu đặc biệt thực hiện một số hành động trên toán hạng.

Trong C#, có 6 loại toán tử tích hợp: Toán tử số học, Toán tử so sánh, Toán tử logic Boolean, Toán tử bitwise và toán tử dịch chuyển, Toán tử đẳng thức và Toán tử linh tinh. Biết tất cả chúng sẽ giúp bạn ngay lập tức trở thành một lập trình viên giỏi hơn.

1. Toán tử số học

Các toán tử sau đây thực hiện các phép tính số học với toán hạng thuộc kiểu số:

  • Toán tử đơn nhất ++ (tăng), -- (giảm), + (cộng) và - (trừ)
  • Các toán tử nhị phân * (nhân), / (chia), % (dư lượng), + (cộng) và - (trừ)

Toán tử tăng++

Toán tử "add one" (hoặc ++) có nghĩa là += 1, nói cách khác, đây là cách nhanh chóng để thêm một số nguyên vào một giá trị số mà không cần phải nhập thêm mã. Toán tử này có thể được thêm vào trước giá trị hoặc sau giá trị, điều này sẽ dẫn đến một hành vi khác:

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

Toán tử giảm dần --

Toán tử "subtract one" ngược lại với ++ (-= 1), nghĩa là nó trừ một số nguyên khỏi một giá trị số. Nó cũng có thể được thêm vào trước hoặc sau một giá trị:

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

Toán tử + và - đơn nhất

Toán tử một ngôi + trả về giá trị của toán hạng của nó và toán tử một ngôi - tính toán số âm của toán hạng của nó.

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

Toán tử nhân *

Toán tử nhân * tính tích của các toán hạng của nó:

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

Toán tử phân chia /

Toán tử chia / chia toán hạng bên trái cho toán hạng bên phải.

Nếu một trong các toán hạng là số thập phân thì toán hạng khác không thể là float hay double, vì cả float và double đều không thể chuyển đổi hoàn toàn thành thập phân. Bạn phải chuyển đổi rõ ràng toán hạng float hoặc double sang kiểu thập phân.

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

Toán tử còn lại %

Toán tử dư % tính số dư sau khi chia toán hạng bên trái cho toán hạng bên phải.

  • Đối với toán hạng của kiểu số nguyên, kết quả của a % b là giá trị được tạo ra bởi 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
  • Đối với toán hạng thập phân, toán tử còn lại % tương đương với toán tử còn lại của loại 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

Toán tử cộng +

Toán tử cộng + tính tổng các toán hạng của nó. Bạn cũng có thể sử dụng toán tử + để nối chuỗi và kết hợp đại biểu.

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

Toán tử trừ -

Toán tử trừ - trừ toán hạng bên phải khỏi toán hạng bên trái. Bạn cũng có thể sử dụng toán tử - để loại bỏ đại biểu.

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

2. Toán tử so sánh

Phép so sánh < (less than), > (greater than), <= (less than or equal), and >= (lớn hơn hoặc bằng), còn được gọi là toán tử quan hệ, so sánh các toán hạng của chúng. Các toán tử đó được hỗ trợ bởi tất cả các kiểu số nguyên và dấu phẩy động.

Nhỏ hơn toán tử <

Toán tử < trả về true nếu toán hạng bên trái của nó nhỏ hơn toán hạng bên phải, ngược lại là 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

Toán tử lớn hơn >

Toán tử > trả về true nếu toán hạng bên trái của nó lớn hơn toán hạng bên phải, nếu không thì trả về 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

Toán tử nhỏ hơn hoặc bằng <=

Toán tử <= trả về true nếu toán hạng bên trái của nó nhỏ hơn hoặc bằng toán hạng bên phải, ngược lại là 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

Toán tử lớn hơn hoặc bằng >=

Toán tử >= trả về true nếu toán hạng bên trái của nó lớn hơn hoặc bằng toán hạng bên phải, ngược lại là 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. Toán tử logic Boolean

Các toán tử sau thực hiện các phép toán logic với toán hạng bool:

  • Đơn nhất ! toán tử (phủ định logic).
  • Nhị phân & (logic AND), | Các toán tử (OR logic) và ^ (OR độc quyền logic). Những toán tử đó luôn đánh giá cả hai toán hạng.
  • Nhị phân && (logic AND có điều kiện) và || (các toán tử logic có điều kiện OR). Những toán tử đó chỉ đánh giá toán hạng bên phải nếu cần thiết.

Toán tử phủ định logic!

Tiền tố đơn nhất ! toán tử tính toán phủ định logic của toán hạng của nó. Nghĩa là, nó tạo ra giá trị đúng nếu toán hạng được đánh giá là sai và sai nếu toán hạng được đánh giá là đúng.

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

Toán tử logic AND &

Toán tử & tính toán logic AND của các toán hạng của nó. Kết quả của x & y là đúng nếu cả x và y đều đánh giá là đúng. Nếu không, kết quả là sai.

Toán tử & đánh giá cả hai toán hạng ngay cả khi toán hạng bên trái đánh giá là sai, do đó kết quả phép toán là sai bất kể giá trị của toán hạng bên phải.

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

Toán tử OR độc quyền về mặt logic ^

Toán tử ^ tính toán OR loại trừ logic, còn được gọi là XOR logic, của các toán hạng của nó. Kết quả của x ^ y là đúng nếu x đánh giá là đúng và y đánh giá là sai hoặc x đánh giá là sai và y đánh giá là đúng. Ngược lại, kết quả là sai. Nghĩa là, đối với toán hạng bool, toán tử ^ tính kết quả tương tự như toán tử bất đẳng thức !=.

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

Toán tử logic OR |

| toán tử tính toán OR logic của các toán hạng của nó. Kết quả của x | y là đúng nếu x hoặc y đánh giá là đúng, nếu không thì kết quả là sai.

The | toán tử đánh giá cả hai toán hạng ngay cả khi toán hạng bên trái đánh giá là đúng, do đó kết quả của phép toán là đúng bất kể giá trị của toán hạng bên phải.

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

Toán tử logic AND có điều kiện &&

Toán tử logic AND có điều kiện &&, còn được gọi là toán tử logic AND "short-circuiting", tính toán logic AND của các toán hạng của nó. Kết quả của x && y là đúng nếu cả x và y đều đánh giá là đúng, nếu không thì kết quả là sai. Nếu x đánh giá là sai thì y không được đánh giá.

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

Toán tử logic OR có điều kiện ||

Toán tử logic OR có điều kiện ||, còn được gọi là toán tử logic OR "short-circuiting", tính toán OR logic của các toán hạng của nó. Kết quả của x || y là đúng nếu x hoặc y đánh giá là đúng. Ngược lại, kết quả là sai. Nếu x đánh giá là đúng thì y không được đánh giá.

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. Toán tử bitwise và shift

Các toán tử sau đây thực hiện các phép toán theo bit hoặc dịch chuyển với toán hạng thuộc kiểu số nguyên hoặc kiểu char:

  • Toán tử Unary ~ (bổ sung bitwise)
  • Toán tử dịch chuyển nhị phân << (left shift) and >> (shift phải)
  • Nhị phân & (logic AND), | Các toán tử (OR logic) và ^ (OR độc quyền logic)

Toán tử bổ sung theo bit ~

Toán tử ~ tạo ra phần bù theo bit cho toán hạng của nó bằng cách đảo ngược từng bit.

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

Toán tử dịch trái <<

Toán tử << dịch toán hạng bên trái của nó sang trái theo số bit được xác định bởi toán hạng bên phải của nó. Để biết thông tin về cách toán hạng bên phải xác định số lượng ca, hãy xem phần Số ca của phần toán tử dịch chuyển.

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

Toán tử dịch phải >>

Toán tử >> dịch toán hạng bên trái sang phải theo số bit được xác định bởi toán hạng bên phải.

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

Vị trí bit trống bậc cao được đặt dựa trên loại toán hạng bên trái như sau:

  • Nếu toán hạng bên trái thuộc loại int hoặc long, toán tử dịch chuyển phải thực hiện phép dịch số học: giá trị của bit quan trọng nhất (bit dấu) của toán hạng bên trái được truyền tới bit trống bậc cao các vị trí. Nghĩa là, các vị trí bit trống bậc cao được đặt thành 0 nếu toán hạng bên trái không âm và được đặt thành 1 nếu toán hạng âm.
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
  • Nếu toán hạng bên trái thuộc loại uint hoặc ulong, toán tử dịch chuyển phải sẽ thực hiện dịch chuyển logic: các vị trí bit trống bậc cao luôn được đặt bằng 0.
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

Toán tử logic AND &

Toán tử & tính toán logic AND theo bit của các toán hạng tích phân của nó.

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

Toán tử OR độc quyền về mặt logic ^

Toán tử ^ tính toán OR loại trừ logic theo bit, còn được gọi là XOR logic theo bit, của các toán hạng tích phân của nó.

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

Toán tử logic OR |

| toán tử tính toán logic OR theo bit của các toán hạng tích phân của nó.

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

5. Toán tử đẳng thức

Các toán tử == (bình đẳng) và != (bất bình đẳng) kiểm tra xem toán hạng của chúng có bằng nhau hay không.

Toán tử đẳng thức ==

Toán tử đẳng thức == trả về true nếu toán hạng của nó bằng nhau, ngược lại trả về 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

Toán tử bất đẳng thức !=

Toán tử bất đẳng thức != trả về true nếu toán hạng của nó không bằng, ngược lại trả về false. Đối với toán hạng của các kiểu dựng sẵn, biểu thức x != y tạo ra kết quả tương tự như biểu thức !(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. Toán tử khác

Các toán tử linh tinh phổ biến là ?: để kiểm tra có điều kiện, :: để truy cập thành viên của không gian tên bí danh và $ để nội suy chuỗi.

?: nhà điều hành

Toán tử điều kiện ?:, còn được gọi là toán tử điều kiện bậc ba, đánh giá một biểu thức Boolean và trả về kết quả của một trong hai biểu thức, tùy thuộc vào việc biểu thức Boolean đánh giá là đúng hay sai, như ví dụ sau đây cho thấy:

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

:: nhà điều hành

Sử dụng vòng loại bí danh không gian tên:: để truy cập thành viên của không gian tên bí danh. Bạn chỉ có thể sử dụng vòng loại:: giữa hai mã định danh. Mã định danh bên trái có thể là bất kỳ bí danh nào sau đây:

  • Bí danh không gian tên được tạo bằng chỉ thị bí danh sử dụng:
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);
}
  • Một bí danh bên ngoài.
  • Bí danh chung, là bí danh không gian tên chung. Không gian tên toàn cục là không gian tên chứa các không gian tên và các kiểu không được khai báo bên trong một không gian tên được đặt tên. Khi được sử dụng với vòng loại::, bí danh chung luôn tham chiếu đến không gian tên chung, ngay cả khi có bí danh không gian tên chung do người dùng xác định.
namespace MyCompany.MyProduct.System
{
    class Program
    {
        static void Main() => global::System.Console.WriteLine("Using global alias");
    }

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

toán tử $

Ký tự đặc biệt $ xác định một chuỗi ký tự là một chuỗi nội suy. Chuỗi nội suy là một chuỗi ký tự có thể chứa các biểu thức nội suy. Khi một chuỗi nội suy được phân giải thành chuỗi kết quả, các mục có biểu thức nội suy sẽ được thay thế bằng biểu diễn chuỗi của kết quả biểu thức.

Trong Chuỗi nội suy, ký hiệu đô la ($) được sử dụng để báo cho trình biên dịch C# rằng chuỗi theo sau nó sẽ được hiểu là Chuỗi nội suy. Dấu ngoặc nhọn đóng gói các giá trị (của các biến) để đưa vào văn bản.

Để xác định một chuỗi ký tự là một chuỗi nội suy, hãy thêm ký hiệu $ vào trước chuỗi đó. Bạn không thể có bất kỳ khoảng trắng nào giữa $ và " bắt đầu một chuỗi ký tự.

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.
Bài viết được đề xuất
Triển khai các phép tính số học cơ bản trong Unity Code
Làm thế nào để trở thành một lập trình viên giỏi hơn trong Unity
Tìm hiểu các hàm và lệnh gọi phương thức
Giới thiệu về ngôn ngữ kịch bản Unity C#
Danh sách thống nhất các từ khóa hữu ích trong C#
Hướng dẫn toàn diện để chuyển đổi xoay vòng trong Unity
Mở ngăn kéo và tủ bằng các phím cụ thể trong Unity