运算符优先级 #

一、优先级概述 #

运算符优先级决定了表达式中运算的顺序。优先级高的运算符先执行,优先级低的后执行。

1.1 基本示例 #

csharp
int result = 2 + 3 * 4;
int result2 = (2 + 3) * 4;

1.2 结合性 #

结合性决定了同优先级运算符的执行顺序:

  • 左结合:从左到右执行
  • 右结合:从右到左执行
csharp
int a = 10 - 5 - 2;

int b = 10;
int c = 20;
int d = 30;
b = c = d;

二、运算符优先级表 #

从高到低排列:

优先级 运算符 说明 结合性
1 x.y, f(x), a[i], x++, x–, new, typeof, checked, unchecked 成员访问、调用、索引、后置递增递减
2 +, -, !, ~, ++x, --x, (T)x, await, &x, *x 一元运算符、类型转换
3 x…y 范围
4 switch, with switch/with表达式
5 * / % 乘法、除法、取余
6 + - 加法、减法
7 << >> >>> 移位
8 < > <= >= is as 关系运算符
9 == != 相等运算符
10 & 按位与
11 ^ 按位异或
12 | 按位或
13 && 逻辑与
14 || 逻辑或
15 ?? ??= 空值合并
16 ?: 条件运算符
17 = += -= *= /= %= &= |= ^= <<= >>= >>>= ??= 赋值运算符
18 => Lambda表达式
19 throw throw表达式

三、常见优先级示例 #

3.1 算术运算符 #

csharp
int a = 2 + 3 * 4;
int b = 2 * 3 + 4;
int c = 2 + 3 * 4 - 5;
int d = 2 * 3 / 4;
int e = 2 + 3 % 2;

3.2 关系与逻辑运算符 #

csharp
bool a = 5 > 3 && 10 < 20;
bool b = 5 > 3 || 10 > 20 && 30 < 40;
bool c = !(5 > 3) || 10 < 20;

3.3 位运算符 #

csharp
int a = 5 & 3 | 2;
int b = 5 | 3 & 2;
int c = 5 ^ 3 & 2;
int d = 5 << 2 | 3;

3.4 赋值与条件运算符 #

csharp
int a = 10;
int b = a = 20;

int c = a > 5 ? 1 : 2;
bool d = a > 5 && b < 30;

四、使用括号明确优先级 #

4.1 推荐做法 #

csharp
bool result1 = (a > b) && (c < d);
int result2 = (a + b) * (c - d);
bool result3 = (a & b) | (c & d);

4.2 复杂表达式 #

csharp
int result = ((a + b) * c - d) / e;

bool isValid = (age >= 18 && age <= 65) && (hasLicense || hasPermit);

int bitwise = (flags & mask) | (otherFlags & otherMask);

五、特殊运算符优先级 #

5.1 条件运算符 #

csharp
int a = 10;
int b = 20;
int result = a > b ? a : b;

bool x = true;
int y = x ? 1 : 2 + 3;
int z = (x ? 1 : 2) + 3;

5.2 空值合并运算符 #

csharp
string a = null;
string b = "Hello";
string c = a ?? b ?? "Default";

int? x = null;
int y = x ?? 0 + 1;
int z = (x ?? 0) + 1;

5.3 Lambda表达式 #

csharp
Func<int, int> f1 = x => x + 1;
Func<int, int> f2 = x => x * 2;
Func<int, int> f3 = x => (x + 1) * 2;

Func<int, bool> predicate = x => x > 0 && x < 10;

六、结合性详解 #

6.1 左结合运算符 #

csharp
int a = 10 - 5 - 2;
int b = 100 / 10 / 2;
bool c = true && false && true;
int d = 10 | 5 | 3;

6.2 右结合运算符 #

csharp
int a, b, c;
a = b = c = 10;

int x = 10;
x += 5;
x *= 2;

bool? result = true ? false : true ? false : true;

七、常见陷阱 #

7.1 位运算与比较 #

csharp
int flags = 5;
int mask = 2;

bool wrong = flags & mask == 2;
bool correct = (flags & mask) == 2;

7.2 条件与赋值 #

csharp
int a = 5;
int b = 10;
int result = a > b ? a = 20 : b = 30;

7.3 移位与算术 #

csharp
int a = 1 << 2 + 3;
int b = (1 << 2) + 3;
int c = 1 << (2 + 3);

八、实战示例 #

8.1 复杂条件表达式 #

csharp
public bool IsEligible(User user, Order order)
{
    return user != null 
        && user.IsActive 
        && (user.Role == "Admin" || user.Role == "Manager")
        && order != null 
        && order.TotalAmount > 0;
}

public bool CanAccess(User user, Resource resource)
{
    return (user?.Role == "Admin" || user?.Permissions.Contains(resource.Id) == true) 
        && resource.IsActive;
}

8.2 位运算表达式 #

csharp
public int ExtractBits(int value, int start, int length)
{
    return (value >> start) & ((1 << length) - 1);
}

public int SetBits(int value, int start, int length, int newValue)
{
    int mask = ((1 << length) - 1) << start;
    return (value & ~mask) | ((newValue << start) & mask);
}

8.3 数值计算 #

csharp
public double CalculateTotal(double price, int quantity, double discount, double tax)
{
    return price * quantity * (1 - discount) * (1 + tax);
}

public double CalculateInterest(double principal, double rate, int years, int timesPerYear)
{
    return principal * Math.Pow(1 + rate / timesPerYear, timesPerYear * years);
}

九、最佳实践 #

9.1 使用括号提高可读性 #

csharp
bool result = (a > b) && ((c < d) || (e == f));

int value = ((a + b) * c) / (d - e);

9.2 拆分复杂表达式 #

csharp
bool isAdult = age >= 18;
bool hasValidId = id != null && id.IsValid;
bool hasPayment = creditCard != null || paypal != null;

if (isAdult && hasValidId && hasPayment)
{
    ProcessOrder();
}

9.3 使用中间变量 #

csharp
double subtotal = price * quantity;
double discountAmount = subtotal * discount;
double taxAmount = (subtotal - discountAmount) * tax;
double total = subtotal - discountAmount + taxAmount;

十、总结 #

运算符优先级要点:

要点 说明
括号优先 使用括号明确优先级
乘除优先于加减 算术运算规则
比较优先于逻辑 关系运算先于逻辑运算
逻辑与优先于或 && 先于 ||
赋值最低 赋值运算符优先级最低

下一步,让我们学习控制流!

最后更新:2026-03-26