[C#] 拆掉複雜邏輯的實用技巧 - Smart Enum

2025-09-11

如果你寫 C# 寫久了,enum 一定是你最早會用、也用最兇的語法之一。

它乾淨、簡單、可讀性好,但只要邏輯稍微複雜一點,

enum 就開始綁手綁腳,大量的 if 或是 switch 又開始了,不利於我們中年工程師..


你常常規劃一些多重的選擇問題+enum 最後一定會變成

switch (method) { case PaymentMethod.LinePush: // .... break; case PaymentMethod.Email: // .... break; }

這樣很多商業邏輯都會被封裝在那一顆裡面,因為主要邏輯判斷都在那個大的 function 

後來我看一些文章有看到一個不錯的規劃方法,這邊我就簡單筆記一下主要是透過把 enum value 變成物件,讓物件去處理邏輯

大家都稱之為 Smart Enum 

這邊我就舉例一個簡單的案例,常遇到的,我們要發送給客戶訊息,但是有分成 Email  ,  SMS , LinePush

1. 寫一個抽象基底這邊我環境是用 用 .NET 9 primary constructor

public abstract class NotificationType { public string Name { get; } protected NotificationType(string name) { Name = name; } public abstract void Send(string message); public abstract bool Validate(string input); public static readonly NotificationType Email = new EmailType(); public static readonly NotificationType Sms = new SmsType(); public static readonly NotificationType PushLine = new PushLineType(); }

static readonly 用來模擬 enum value


2. 寫三個 Smart Enum Value(每個都有自己的行為)

public sealed class EmailType : NotificationType { public EmailType() : base("Email") { } public override bool Validate(string email) { //Validate Email Logic return email.Contains("@"); } public override void Send(string message) { //Send Logic Console.WriteLine("Send email:" + message); } } public sealed class SmsType : NotificationType { public SmsType() : base("SMS") { } public override bool Validate(string number) { //Validate Text Logic return number.StartsWith("09") && number.Length == 10; } public override void Send(string message) { Console.WriteLine("Send SMS:" + message); //Send Logic } } public sealed class PushLineType : NotificationType { public PushLineType() : base("PushLine") { } public override bool Validate(string token) { return token.Length > 10; } public override void Send(string message) => Console.WriteLine($"Send Push: {message}"); }

每個 Smart Enum value 有自己的 驗證邏輯、發送邏輯


3. 接下來就不用 switch 了

var typeSMS = NotificationType.Sms; if (typeSMS.Validate("0912345678")) { typeSMS.Send("Hello! Moto!"); } var typeLine = NotificationType.PushLine; if (typeLine.Validate("token-123456789")) { typeLine.Send("Hello! LINE!"); } var typeEmail = NotificationType.Email; if (typeLine.Validate("foo@sample.com")) { typeLine.Send("Hello! EMAIL!"); } //Send SMS:Hello! Moto! //Send Push: Hello! LINE! //Send Push: Hello! EMAIL!

沒有 if、沒有 switch、邏輯全部封裝在類別裡面,而且每個也可以被單一測試維護


結論 -

如果你發現 enum 已經快撐不住你的完美主義的程式,那就改用 Smart Enum。不只是"可以寫得很 OOP"

維護起來比 switch-based 程式乾淨太多



當麻許的碎念筆記 2014 | Donma Hsu Design.