Unity C# 必知运算符
Unity 是一款游戏引擎,在功能方面为开发人员提供了很多便利,使他们可以完全专注于开发过程。它使用 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
除法运算符 /
除法运算符 / 将其左侧操作数除以其右侧操作数。
如果其中一个操作数是十进制,则另一个操作数既不能是浮点数也不能是双精度数,因为浮点数和双精度数都不能隐式转换为十进制。您必须将浮点数或双精度操作数显式转换为十进制类型。
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 操作数执行逻辑运算:
- 一元 !(逻辑否定)运算符。
- 二进制 &(逻辑与)、|(逻辑或)和 ^(逻辑排他或)运算符。这些运算符始终计算两个操作数。
- 二进制 &&(条件逻辑与)和 ||(条件逻辑或)运算符。这些运算符仅在必要时才计算右侧操作数。
逻辑否定运算符!
一元前缀 ! 运算符计算其操作数的逻辑非。也就是说,如果操作数计算结果为 false,则结果为 true;如果操作数计算结果为 true,则结果为 false。
bool passed = false;
Debug.Log(!passed); // output: True
Debug.Log(!true); // output: False
逻辑与运算符 &
& 运算符计算其操作数的逻辑与。如果 x 和 y 的计算结果均为真,则 x & y 的结果为真。否则,结果为假。
即使左侧操作数的计算结果为假,& 运算符也会计算两个操作数,因此无论右侧操作数的值如何,运算结果都为假。
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。否则,结果为 false。也就是说,对于 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 或 y 的计算结果为真,则 x | y 的结果为真,否则结果为假。
即使左侧操作数的计算结果为真,| 运算符也会计算两个操作数,因此无论右侧操作数的值如何,运算结果都为真。
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
条件逻辑与运算符 &&
条件逻辑与运算符 &&,也称为 "short-circuiting" 逻辑与运算符,计算其操作数的逻辑与。如果 x 和 y 的计算结果均为真,则 x && y 的结果为真,否则结果为假。如果 x 的计算结果为假,则不计算 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
条件逻辑或运算符 ||
条件逻辑或运算符 || 也称为 "short-circuiting" 逻辑或运算符,计算其操作数的逻辑或。如果 x 或 y 的计算结果为真,则 x || y 的结果为真。否则,结果为假。如果 x 的计算结果为真,则不计算 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 类型,右移运算符将执行算术移位:左侧操作数的最高有效位(符号位)的值将传播到高位空位位置。也就是说,如果左侧操作数为非负数,则将高位空位位置设置为零,如果为负数,则设置为一。
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 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);
}
- 外部别名。
- 全局别名,即全局命名空间别名。全局命名空间是包含未在命名命名空间内声明的命名空间和类型的命名空间。当与:: 限定符一起使用时,全局别名始终引用全局命名空间,即使存在用户定义的全局命名空间别名。
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.