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

#region 指令正確使用指南:重構勝過折疊

     編輯:關於.NET

前言

每位 C# 開發者都見過 #region,它能將程式碼區塊摺疊,讓檔案看起來整潔。但濫用 #region 往往掩蓋了程式碼品質問題。本文探討何時適合使用 #region,何時應改用重構手法。

錯誤示範 1:在大型方法中使用 #region

問題程式碼

public void DoSomething()
{
    bool shouldIDoSomething;
    #region Decide if I should do something
    if (needToDoSomething && haventDoneSomethingThisDay)
        shouldIDoSomething = true;
    else
    {
        // 複雜邏輯決定 shouldIDoSomething
    }
    #endregion
    
    if (shouldIDoSomething)
    {
        done++;
    }
}

摺疊後雖然乾淨:

public void DoSomething()
{
    bool shouldIDoSomething;
    [Decide if I should do something]
    if (shouldIDoSomething)
    {
        done++;
    }
}

但這本質上是將一個函式內嵌在另一個函式中,違反「單一職責原則」。

正確做法:提取方法

public void DoSomething()
{
    if (ShouldIDoSomething())
    {
        done++;
    }
}

private bool ShouldIDoSomething()
{
    if (needToDoSomething && haventDoneSomethingThisDay)
        return true;
    
    // 複雜邏輯...
    return false;
}

優點:降低複雜度、可獨立測試、意圖更清晰。

小結 1:#region 不適合用在大型方法內。當你在方法中寫 #region 時,停下來思考:這段程式碼能否提取為獨立方法?大多數情況下,答案是肯定的。

錯誤示範 2:用 #region 包裹整個方法

問題程式碼

#region Get Customer
public void GetCustomer()
{
    // 取得客戶邏輯
}
#endregion

#region Save Customer
public void SaveCustomer()
{
    // 儲存客戶邏輯
}
#endregion

摺疊後:

[Get Customer]
[Save Customer]

這樣反而降低可讀性:閱讀者必須逐一展開才能看程式碼。IDE 本身就有「摺疊所有方法」功能,不需要 #region 協助。

小結 2:不要因為「能用」就使用 #region。它無法消除複雜度,只是暫時隱藏。

錯誤示範 3:用 #region 分組類別內的多組方法

問題程式碼

public class PriceCalculator
{
    public decimal CalculatePrice()
    {
        decimal price = 100m;
        decimal discount = CalculateDiscount();
        return price * (1m - discount);
    }
    
    #region Discount Calculation
    private decimal CalculateDiscount()
    {
        decimal discount = 0m;
        if (CanApplyDiscount())
            discount = 0.05m;
        return discount;
    }
    
    private bool CanApplyDiscount()
    {
        // 複雜邏輯...
    }
    // 更多折扣計算方法...
    #endregion
}

這個類別有兩個職責:價格計算、折扣計算。#region 掩蓋了這個設計缺陷。

正確做法:提取類別

public class PriceCalculator
{
    private readonly IDiscountCalculator _discountCalculator;
    
    public PriceCalculator(IDiscountCalculator discountCalculator)
    {
        _discountCalculator = discountCalculator;
    }
    
    public decimal CalculatePrice()
    {
        decimal price = 100m;
        decimal discount = _discountCalculator.Calculate();
        return price * (1m - discount);
    }
}

public interface IDiscountCalculator
{
    decimal Calculate();
}

public class StandardDiscountCalculator : IDiscountCalculator
{
    public decimal Calculate()
    {
        // 折扣邏輯...
    }
}

符合單一職責原則,且便於測試與擴展。

小結 3:將一組相關方法提取到職責單一的新類別中,優於用 #region 分組。

#region 的正確使用場景

在類別層級,用於組織結構性元素:

public class SomeClass
{
    #region Events
    // 事件定義
    #endregion
    
    #region Fields
    // 私有欄位
    #endregion
    
    #region Properties
    // 屬性
    #endregion
    
    #region Methods
    // 方法
    #endregion
    
    #region Nested Types
    // 巢狀類型
    #endregion
}

摺疊後:

public class SomeClass
{
    [Events]
    [Fields]
    [Properties]
    [Methods]
    [Nested Types]
}

這能幫助快速導覽類別結構,不影響程式碼品質。

核心原則

  1. Region 無法消除複雜度,只能隱藏。真正控制複雜度的是:小型、清晰、單一職責的方法與類別。
  2. 優先重構,其次摺疊。當想用 #region 時,先問自己:能否提取方法?能否提取類別?
  3. 類別層級結構組織是 #region 合理的用途;方法內部與方法層級分組則通常是重構機會。

當你寫出小巧、清晰、重點突出的方法和類別時,你甚至會發現 #region 是不必要的。

本文翻譯自:About #region Preprocessor Directive

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