首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 邏輯運算式與短路求值:&&、|| 運算子深度解析與實戰模式

     編輯:關於C#

邏輯運算式結合關係運算與布林邏輯,構成程式決策的核心。C# 的 && (條件 AND) 與 || (條件 OR) 採用短路求值,不僅影響效能,更關係執行正確性與副作用控制。

短路求值機制

運算子短路條件行為
a && ba == false直接回傳 false,不評估 b
a || ba == true直接回傳 true,不評估 b

關鍵含意:b 可能包含副作用(方法呼叫、屬性存取、遞增運算),短路會導致其完全不執行。

實戰範例:短路的威力與陷阱

✅ 防禦性程式設計 — 避免 NullReferenceException

// 安全:obj 為 null 時,不執行 obj.Method()
if (obj != null && obj.IsValid()) { ... }

// 危險:使用 & 會評估右邊,拋出例外
if (obj != null & obj.IsValid()) { ... } // 錯誤!

✅ 效能優化 — 昂貴運算後置

// 快速檢查先行,昂貴運算只在必要時執行
if (cache.Contains(key) || ComputeExpensiveValue(key)) { ... }

// 反例:總是執行昂貴運算
if (ComputeExpensiveValue(key) || cache.Contains(key)) { ... }

⚠️ 副作用陷阱 — 遞增運算被吞噬

int x = 0;
bool result = false || (x++ > 0); 
// result = false, x = 1 (右邊執行了)

result = true || (x++ > 0); 
// result = true, x = 1 (右邊被短路,x 不遞增!)

閏年判斷:經典邏輯運算式

bool IsLeapYear(int year)
{
    // 400 整除 || (4 整除 && 非 100 整除)
    return (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0));
}

// 短路優化版:優先檢查最常見情況
bool IsLeapYearOptimized(int year)
{
    if (year % 4 != 0) return false;      // 75% 情況快速排除
    if (year % 100 == 0) return year % 400 == 0;
    return true;
}

邏輯運算子優先級與結合性

優先級 (高→低):! > && > ||
結合性:左結合

隱含括號範例:

a || b && c     // a || (b && c)
!a && b || c    // ((!a) && b) || c
a && b || c && d // (a && b) || (c && d)

位元邏輯運算子 vs 條件邏輯運算子

特性&, |&&, ||
短路求值否 (總評估兩邊)是
適用類型bool、整數 (位元運算)僅 bool
可多載是否 (但可多載 true/false 運算子)
用途位元遮罩、旗標、需雙邊副作用一般布林邏輯、防禦性檢查

位元邏輯運算子實用場景

// 兩個副作用都必須執行
if (ValidateInput() | SaveToDatabase()) { ... }

// 位元旗標操作
[Flags] enum Flags { A = 1, B = 2, C = 4 }
var f = Flags.A | Flags.B; // 合併
bool hasA = (f & Flags.A) != 0; // 檢測

最佳實踐總結

  1. 預設使用 &&/|| — 短路符合直覺、效能更好、防禦性更強
  2. 明確需要雙邊副作用 時才用 &/|
  3. 將低成本/高概率短路條件前置 — 最大化短路效益
  4. 複雜邏輯提取為具名方法/屬性 — 提升可讀性與可測試性
  5. 避免在邏輯運算式中放置副作用 — 改為明確陳述式

進階:使用者定義型別的短路支援

public struct Optional
{
    public bool HasValue { get; }
    public T Value { get; }
    
    // 必須同時定義 true/false 運算子才能支援 &&/||
    public static bool operator true(Optional opt) => opt.HasValue;
    public static bool operator false(Optional opt) => !opt.HasValue;
    
    public static Optional operator &(Optional a, Optional b) 
        => a.HasValue ? b : a; // 短路語意:a 無值則直接回傳 a
    
    public static Optional operator |(Optional a, Optional b) 
        => a.HasValue ? a : b;
}

深入理解短路求值語意,能編寫更健壯、高效且符合直覺的條件邏輯,是 C# 開發者的核心功力之一。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved