IRONSOFTWAREHOME

在 C# 中重構條件 if:避免條件雜亂與 Derek Comartin

枚舉並不可怕。 到處都是條件式

Derek Comartin

11m 03s

在 C# 中,條件語句如 if 語句、if else 語句和 switch 語句是基本工具。 但是,當這些結構被過度使用時會發生什麼——特別是與枚舉綁定時? Derek Comartin 在他的影片"枚舉並不可怕。到處都是條件式 在這個影片中,Derek帶我們透過一個詳細的重構,用更清晰、更易於維護的模式替換掉廣泛的條件邏輯。

在這篇文章中,我們將一步步走過Derek的思路,使用他的時間戳作為錨點。 我們還會探索他的想法如何應用於 C# 中常見的條件模式,如三元運算符、else 語句和 switch-case 結構——突出它們在大型程式碼庫中的問題以及如何重構以達到更好的設計。

條件式爆炸:真正的問題

Derek 首先展示了一個檢查產品型別的 if 語句:

if (productType == ProductType.Template || productType == ProductType.Ebook)

乍看之下,上面的條件 if 看起來很直接。 但是Derek警告,這種語句評估給定條件,然後僅在條件為真時執行程式碼塊——這當這種邏輯到處重複時變成了一個問題。

您可能會在另一個方法或類中再次看到這個塊:

if (offeringType == ProductType.Template || offeringType == ProductType.Ebook)

Derek 解釋說,這種模式很快就在大型系統中蔓延。 相同的 if else 邏輯出現在多個服務中,當新增新的枚舉值時會造成不一致和錯誤。 例如,當您引入新的產品型別如 Video 時會怎樣? 您將需要記得更新每一個包含此條件表達式的程式碼塊。

重複放大了複雜性

在以下範例中,Derek深入巢狀條件。 在一種方法中,一個 if else 語句檢查相同的枚舉,並將結果傳遞給另一種方法,該方法也包含類似的檢查。

語句檢查 Template 或 Ebook,並返回某些東西——否則返回 null。 Derek 指出,這種冗餘不僅使程式碼更長,還帶來維護風險。 相同的邏輯被複製到多個文件中,導致控制流程混亂。

如果您的系統要求您每次觸摸枚舉時都要新增預設情況,那麼您就知道有些地方出錯了。

改變我們對條件式的思考方式

而不是不斷使用 if else 檢查型別,Derek 建議問一個更好的問題:

產品是否具有可下載的特性?

這對意圖的表達更好。 它使您的程式碼更具可讀性並減少對枚舉的依賴。 而不是編寫一個具有兩個條件的 if 語句如:

if (product.Type == ProductType.Template || product.Type == ProductType.Ebook)

您可以簡單地在模型中封裝該邏輯並編寫:

if (product.HasDownloadableResource())

僅在存在可下載資源時返回 true——減少對複雜條件表達式的需求。

從 If 語句到封裝行為

為了解決核心問題,Derek 引入了 DownloadableResource 型別。 此型別包括一個下載 URL 和一個預設文件名。 它成為您的領域中的一級部分,而非依賴於 if 語句來推導出它。

現在,取而代之重複這個:

if (product.Type == ProductType.Template)
{
    // Generate file name
}
else if (product.Type == ProductType.Ebook)
{
    // Generate file name
}

您編寫這個:

var downloadable = product.GetDownloadableResource();
if (downloadable != null)
{
    Console.WriteLine(downloadable.FileName);
}

這大大簡化了邏輯並消除了對 else 語句分支甚至 switch 語句的需要。

運行時超越編譯時:一個戰略轉變

Derek 更進一步,解釋了一個重要的設計選擇:將邏輯從編譯時轉換為運行時。這意味著在運行時查詢系統以查看產品是否存在 DownloadableResource。 如果存在,則採取行動。 如果不,在跳過它。

他指出,此舉將靜態 if else 邏輯轉變為運行時查詢。 這可能會增加一個資料庫調用,但它減少了巢狀的 if else 邏輯並集中行為。 這提高了大規模的可維護性。

使用繼承來管理可下載產品

Derek 探索的另一種方法是繼承。 您可以建立一個抽象基類 Product,然後定義派生型別如 Ebook、Template 或 OfflineCourse。

每一種都覆蓋方法如:

public virtual string GetDownloadUrl() { ... }

這種方法允許每個產品自行處理邏輯。 雖然這避免了 switch 語句或多個條件語句,但 Derek 指出,如果不小心,您仍可能會在內部編寫條件表達式。

不使用繼承仍能更好地封裝

如果繼承顯得過於繁瑣,Derek 建議使用明確的型別,如 DownloadableProduct,它包含自己的屬性和方法——而不是被綁定到一個層次結構上。

在您的程式中,它可能看起來像這樣:

var downloader = new DownloadableProduct(product);
Console.WriteLine(downloader.GetDefaultFileName());

不需要使用 if else 或 switch 語句來決定行為——每個物件知道要做什麼。

輕量解決方案:在枚舉上使用擴展方法

如果您還沒準備好放棄枚舉,Derek 提出了一個輕量解決方案——建立擴展方法:

public static bool IsDownloadable(this ProductType type)
{
    return type == ProductType.Template || type == ProductType.Ebook;
}

現在不用編寫:

if (product.Type == ProductType.Template || product.Type == ProductType.Ebook)

您可以將其簡化為:

if (product.Type.IsDownloadable())

這將您的邏輯集中化,避免一次又一次地重複大括號和程式碼塊。

避免過度使用三元運算符和 switch

Derek 也警告不要過度使用如三元運算符等簡寫:

string filename = product.Type == ProductType.Template ? "template.pdf" : "default.pdf";

雖然這是有效的語法,但在邏輯變得複雜時,它可能會容易出錯且難以閱讀。 尤其是當條件判斷為假時,可能會以微妙的方式分配錯誤的值。

同樣地,帶有 break 語句和預設情況的 switch 也陷入這個陷阱。更好的是請物件給予行為而不是使用 switch-case 邏輯。

結論:更智能的控制與更少的條件群雜

總之,Derek 的影片不僅僅是批評枚舉——而是對我們如何在它們周圍使用條件 if 結構的批判。 通過將 if else 和 switch 語句分散到程式碼庫中,您使得系統更加難以測試、維護和演化。

無論您選擇封裝、運行時查詢、繼承還是簡單的擴展方法,目標仍然是:減少條件式,並將邏輯移動到其應所在的位置。

記住:

  • 條件式並不壞。

  • 條件群雜是問題。

  • 優雅的程式碼不依賴於類中零散的多個 if else 語句。

  • 評估您的上下文並據此重構。

正如 Derek 所說,"這取決於您的上下文。" 但有一點是確定的:產品不僅僅只是產品——有時它是重新思考您設計的一個信號。

Earn More by Sharing What You Love

Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Let's Stay in Touch!

Join our newsletter, you’ll get exclusive access on article updates. We value your privacy

Key in blue circle

立即免費取得 30 天試用金鑰

Your trial license will be sent to your email address

無任何限制。100% 解鎖。無需信用卡。

bullet_checked無需信用卡或建立帳號無任何限制。100% 解鎖。無需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
獲取您的無義務諮詢
填寫以下表格或發送電子郵件至sales@ironsoftware.com
您的詳細資訊將始終保密。
被全球數百萬工程師信任
Iron Software的客戶標誌
立即獲取您的30天試用金鑰
無需信用卡或帳戶建立