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

C# 擴展方法實現流暢式 Switch/Case 模式

     編輯:C# 入門

前言

傳統 switch/case 語句在 C# 中功能有限,無法直接對複雜物件進行模式匹配 (C# 7.0+ 才引入 pattern matching)。本文介紹一種利用擴展方法構建的流暢式 Switch/Case/Default 鏈式 API,支援值比較、條件判斷、預設分支與中斷控制,提升代碼可讀性。

核心實作

public static class SwitchCaseExtension
{
    // 1. Case 容器
    public class SwitchCase<TCase, TOther> where TCase : IEquatable<TCase>
    {
        public TCase Value { get; private set; }
        public Action<TOther> Action { get; private set; }
        public bool IsMatched { get; set; }

        public SwitchCase(TCase value, Action<TOther> action)
        {
            Value = value;
            Action = action;
            IsMatched = false;
        }
    }

    // 2. Switch 起始
    public static SwitchCase<TCase, TOther> Switch<TCase, TOther>(
        this TCase value, Action<TOther> action) where TCase : IEquatable<TCase>
    {
        return new SwitchCase<TCase, TOther>(value, action);
    }

    public static SwitchCase<TCase, TOther> Switch<TInput, TCase, TOther>(
        this TInput input, Func<TInput, TCase> selector, Action<TOther> action) 
        where TCase : IEquatable<TCase>
    {
        return new SwitchCase<TCase, TOther>(selector(input), action);
    }

    // 3. Case 分支 (值匹配)
    public static SwitchCase<TCase, TOther> Case<TCase, TOther>(
        this SwitchCase<TCase, TOther> sc, TCase option, TOther other, bool breakAfter = true) 
        where TCase : IEquatable<TCase>
    {
        return Case(sc, c => c.Equals(option), other, breakAfter);
    }

    // 4. Case 分支 (條件判斷)
    public static SwitchCase<TCase, TOther> Case<TCase, TOther>(
        this SwitchCase<TCase, TOther> sc, Predicate<TCase> predict, TOther other, bool breakAfter = true) 
        where TCase : IEquatable<TCase>
    {
        if (sc == null || sc.IsMatched) return sc;
        if (predict(sc.Value))
        {
            sc.Action(other);
            sc.IsMatched = true;
            return breakAfter ? null : sc;
        }
        return sc;
    }

    // 5. Default 分支
    public static void Default<TCase, TOther>(
        this SwitchCase<TCase, TOther> sc, TOther other) 
        where TCase : IEquatable<TCase>
    {
        if (sc == null || sc.IsMatched) return;
        sc.Action(other);
    }
}

使用範例

string typeName = string.Empty;
typeId.Switch(s => typeName = s)
    .Case("A", "Type A")
    .Case("B", "Type B")
    .Case("C", "Type C")
    .Default("Unknown");

// 更複雜:條件判斷
int number = 42;
number.Switch(n => Console.WriteLine($"Result: {n}"))
    .Case(n => n > 100, "Large")
    .Case(n => n > 50, "Medium")
    .Case(n => n > 0, "Small")
    .Default("Zero or Negative");

優缺點分析

優點缺點
鏈式語法流暢,閱讀如自然語言非語言原生,IDE 智能提示不如原生 switch
支援複雜條件判斷 (Predicate)效能略低於原生 switch (委託呼叫開銷)
可對任何實作 IEquatable 的類型使用需引入擴展方法命名空間
Default 自動處理未匹配情況breakAfter 預設 true 可能不符合貫穿需求

現代替代方案

C# 7.0+ 內建 Pattern Matching 已大幅增強 switch 表達式:

string result = typeId switch
{
    "A" => "Type A",
    "B" => "Type B",
    "C" => "Type C",
    _ => "Unknown"
};

// 更進階
string desc = number switch
{
    > 100 => "Large",
    > 50 => "Medium",
    > 0 => "Small",
    _ => "Zero or Negative"
};

新專案建議優先使用原生 pattern matching,僅在舊版 .NET Framework 專案中考慮此擴展方案。

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