擴充方法 - 以取得 BMI 為例

Dec 16, 2019




情境

假設目前系統有一個 People 類別,原來記錄著 HeightWeight 兩個屬性,現在想提供 BMI 資訊。

    public class People
    {
        public int Height { get; set; }
        public int Weight { get; set; }
    }

方案

不同實做方式,影響原有類別 ( 此例中為 People ),也影響呼叫方的使用方式,以下列示不同方案,提供參考。

直接在 People 類別中加上屬性

最直接且直覺的方式,就是透過提供一個唯讀的屬性或方法提供 BMI 的取得。

public class People
{
    public int Height { get; set; }
    public int Weight { get; set; }
    public double CountBMI() 
    {
        return Weight/Height;
    }
}    

使用情境。

var John = new People();
var JohnBMI = John.CountBMI();

透過 Counter 類別提供計算功能

代入透過 BMI 測量機量測試的概念,將 BMI 的取得視為 Counter 的計算結果,額外新增 BMICount 類別,提供 Counting 介面,以計算 People 類別的對應 BMI 值。

public class People
{
    public int Height { get; set; }
    public int Weight { get; set; }
}

public Class BMICount
{
    public double Counting(People pi_objPeople)
    {
        return pi_objPeople.Weight/pi_objPeople.Height;
    }
}

使用情境。

var John = new People();
var Counter = new BMICount();
var JohnBMI = Counter.Counting(John);

透過 Counter 類別提供計算功能,採用靜態方法

類似前面的方案,但操作介面改以靜態方法處理,在此例中,因為 BMICountCounting 操作,並未透過建構元傳入參數或預先處理,所以採用靜態方法,在呼叫端看來較為簡約。

public class People
{
    public int Height { get; set; }
    public int Weight { get; set; }
}

public Class BMICount
{
    public Static double Counting(People pi_objPeople)
    {
        return pi_objPeople.Weight/pi_objPeople.Height;
    }
}
var John = new People();
var JohnBMI = BMICounter.Counting(John);

利用擴充方法,提供 People 類別 BMI 方法

透過 C# 提供的 擴充方法 寫法,讓原本的資料物件 People 保持原有狀態,透過額外撰寫擴展方法達成 BMI 的計算邏輯。
對於第三方元件,因為缺少原始碼,或重新編譯不便的原因,無法或難以新增功能時,透過擴充方法可以提供直覺的呼叫模式。

public class People
{
    public int Height { get; set; }
    public int Weight { get; set; }
}

public Static Class PeopleExtension
{
    public Static double Counting(this People pi_objPeople)
    {
        return pi_objPeople.Weight/pi_objPeople.Height;
    }
}
var John = new People();
var JohnBMI = John.BMI;

結語

可以透過各種不同的程式寫法達成相同的效果,應該考量使用者的語境來決定適當的撰寫方式。