Unity C# 必须了解的运算符

Unity 是一个游戏引擎,在功能方面为开发人员做了很多 "heavy-lifting" 工作,让他们完全专注于开发过程。它使用 C# 作为主要编程语言。

与任何编程语言一样,C# 由一组特殊函数、类型、类、库等组成,但它也有一个特殊符号(运算符)列表,每个符号都有自己的功能。在这篇文章中,我将列出这些符号并解释它们的作用,以便您下次打开脚本时,您能够快速理解每个部分的含义。

C# 中的运算符是一些对操作数执行某些操作的特殊符号。

C# 中,有 6 种内置运算符:算术运算符、比较运算符、布尔逻辑运算符、按位和移位运算符、相等运算符和杂项运算符。了解所有这些将使您立即成为更好的程序员。

1. 算术运算符

以下运算符对数值类型的操作数执行算术运算:

  • 一元 ++(递增)、--(递减)、+(加)和 -(减)运算符
  • 二进制 *(乘法)、/(除法)、%(余数)、+(加法)和 -(减法)运算符

自增运算符++

"add one" 运算符(或 ++)意味着 += 1,换句话说,这是一种将一个整数与数值相加的快速方法,而无需键入额外的代码。该运算符可以添加在值之前或值之后,这将导致不同的行为:

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

自减运算符 --

"subtract one" 运算符与 ++ (-= 1) 相反,这意味着它从数值中减去一个整数。它也可以添加在值之前或之后:

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

一元 + 和 - 运算符

一元 + 运算符返回其操作数的值,一元 - 运算符计算其操作数的数值否定。

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

乘法运算符 *

乘法运算符 * 计算其操作数的乘积:

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

分部操作员/

除法运算符 / 将其左侧操作数除以右侧操作数。

如果其中一个操作数是十进制,则另一个操作数既不能是 float 也不能​​是 double,因为 float 和 double 都不能隐式转换为十进制。您必须将 float 或 double 操作数显式转换为十进制类型。

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

余数运算符 %

余数运算符 % 计算左侧操作数除以右侧操作数后的余数。

  • 对于整数类型的操作数,a % b 的结果是 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
  • 对于小数操作数,余数运算符 % 等效于 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

加法运算符 +

加法运算符 + 计算其操作数之和。您还可以使用 + 运算符进行字符串连接和委托组合。

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

减法运算符 -

减法运算符 - 从左侧操作数中减去右侧操作数。您还可以使用 - 运算符来删除委托。

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

2. 比较运算符

< (less than), > (greater than), <= (less than or equal), and >=(大于或等于)比较(也称为关系运算符)比较其操作数。所有整型和浮点数值类型都支持这些运算符。

小于运算符<

如果 < 运算符的左侧操作数小于右侧操作数,则返回 true,否则返回 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

大于运算符 >

如果 > 运算符的左侧操作数大于右侧操作数,则返回 true,否则返回 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

小于或等于运算符 <=

如果 <= 运算符的左侧操作数小于或等于右侧操作数,则返回 true,否则返回 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

大于或等于运算符 >=

如果 >= 运算符的左侧操作数大于或等于右侧操作数,则返回 true,否则返回 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. 布尔逻辑运算符

以下运算符使用 bool 操作数执行逻辑运算:

  • 一元!(逻辑非)运算符。
  • 二进制 &(逻辑与),| (逻辑或)和^(逻辑异或)运算符。这些运算符始终评估两个操作数。
  • 二进制 &&(条件逻辑 AND)和 || (条件逻辑或)运算符。这些运算符仅在必要时才计算右侧操作数。

逻辑否定运算符!

一元前缀 ! 运算符计算其操作数的逻辑非。也就是说,如果操作数的计算结果为 false,则生成 true;如果操作数的计算结果为 true,则生成 false。

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

逻辑与运算符 &

& 运算符计算其操作数的逻辑与。如果 x 和 y 的计算结果都为 true,则 x & y 的结果为 true。否则,结果为 false。

即使左侧操作数的计算结果为 false,& 运算符也会计算两个操作数,因此无论右侧操作数的值如何,运算结果都为 false。

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

逻辑异或运算符 ^

^ 运算符计算其操作数的逻辑异或,也称为逻辑异或。如果 x 计算结果为 true 并且 y 计算结果为 false,或者 x 计算结果为 false 并且 y 计算结果为 true,则 x ^ y 的结果为 true。否则,结果为假。也就是说,对于 bool 操作数,^ 运算符计算的结果与不等运算符 != 相同。

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

逻辑或运算符 |

| 的 | 运算符计算其操作数的逻辑或。x | 的结果 如果 x 或 y 计算结果为真,则 y 为真,否则结果为假。

| 即使左侧操作数的计算结果为 true,运算符也会计算两个操作数,因此无论右侧操作数的值如何,运算结果都为 true。

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

条件逻辑与运算符 &&

条件逻辑 AND 运算符 &&,也称为 "short-circuiting" 逻辑 AND 运算符,计算其操作数的逻辑 AND。如果 x 和 y 的计算结果都为 true,则 x && y 的结果为 true,否则结果为 false。如果 x 计算结果为 false,则不计算 y。

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

条件逻辑或运算符 ||

条件逻辑 OR 运算符 || 也称为 "short-circuiting" 逻辑 OR 运算符,计算其操作数的逻辑 OR。x || 的结果 如果 x 或 y 计算结果为真,则 y 为真。否则,结果为假。如果 x 计算结果为 true,则不计算 y。

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. 按位和移位运算符

以下运算符对整型数值类型或字符类型的操作数执行按位或移位运算:

  • 一元 ~(按位求补)运算符
  • 二进制 << (left shift) and >>(右移)移位运算符
  • 二进制 &(逻辑与),| (逻辑或)和^(逻辑异或)运算符

按位求补运算符 ~

~ 运算符通过反转每个位来生成其操作数的按位补码。

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

左移运算符 <<

<< 运算符将其左侧操作数向左移动其右侧操作数定义的位数。有关右侧操作数如何定义移位计数的信息,请参阅移位运算符的移位计数部分。

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

右移运算符 >>

>> 运算符将其左侧操作数右移其右侧操作数定义的位数。

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

高阶空位位置根据左侧操作数的类型设置,如下所示:

  • 如果左侧操作数的类型为 int 或 long,则右移运算符执行算术移位:左侧操作数的最高有效位(符号位)的值传播到高位空位职位。也就是说,如果左侧操作数为非负,则高阶空位位置设置为零,如果左侧操作数为负,则设置为 1。
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
  • 如果左侧操作数的类型为 uint 或 ulong,则右移运算符执行逻辑移位:高阶空位位置始终设置为零。
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

逻辑与运算符 &

& 运算符计算其整数操作数的按位逻辑与。

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

逻辑异或运算符 ^

^ 运算符计算其整数操作数的按位逻辑异或,也称为按位逻辑异或。

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

逻辑或运算符 |

| 的 | 运算符计算其整数操作数的按位逻辑或。

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

5. 相等运算符

==(相等)和 !=(不等)运算符检查它们的操作数是否相等。

相等运算符==

如果操作数相等,则等于运算符 == 返回 true,否则返回 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

不等式运算符!=

如果操作数不相等,不等运算符 != 返回 true,否则返回 false。对于内置类型的操作数,表达式 x != y 生成与表达式 !(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. 杂项运算符

常见的杂项运算符包括用于条件检查的 ?:、用于访问别名命名空间的成员的:: 以及用于字符串插值的 $。

?: 操作员

条件运算符 ?: 也称为三元条件运算符,它计算布尔表达式并返回两个表达式之一的结果,具体取决于布尔表达式的计算结果是 true 还是 false,如以下示例所示:

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

:: 操作员

使用命名空间别名限定符:: 访问别名命名空间的成员。您只能在两个标识符之间使用:: 限定符。左侧标识符可以是以下任何别名:

  • 使用 using 别名指令创建的命名空间别名:
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);
}
  • 外部别名。
  • 全局别名,即全局命名空间别名。全局命名空间是包含未在命名空间内声明的命名空间和类型的命名空间。当与:: 限定符一起使用时,全局别名始终引用全局命名空间,即使存在用户定义的全局命名空间别名。
namespace MyCompany.MyProduct.System
{
    class Program
    {
        static void Main() => global::System.Console.WriteLine("Using global alias");
    }

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

$ 运算符

$ 特殊字符将字符串文字标识为内插字符串。插值字符串是可能包含插值表达式的字符串文字。当插值字符串解析为结果字符串时,具有插值表达式的项将替换为表达式结果的字符串表示形式。

在插值字符串中,美元符号 ($) 用于告诉 C# 编译器将其后面的字符串解释为插值字符串。大括号封装要包含在文本中的(变量的)值。

要将字符串文字标识为内插字符串,请在其前面添加 $ 符号。开始字符串文字的 $ 和 " 之间不能有任何空格。

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.
推荐文章
了解函数和方法调用
Unity C# 脚本语言简介
在 Unity 代码中实现基本算术运算
如何成为一名更好的 Unity 程序员
在 Unity 中创建交互式对象
在 Unity 中实现动力学交互
在 Unity 中使用特定钥匙打开抽屉和橱柜