擴充方法讓你在不修改原型別、不繼承的前提下,為現有型別「新增」實例方法。語法要求:
static 類別中staticthis 修飾詞,指定被擴充的型別public static class DataReaderExtensions
{
public static string GetString(this IDataReader dr, string columnName)
=> dr.GetString(dr.GetOrdinal(columnName));
public static int GetInt32(this IDataReader dr, string columnName)
=> dr.GetInt32(dr.GetOrdinal(columnName));
}
使用時:
using MyExtensions; // 必須引入命名空間
var name = reader.GetString("UserName"); // IntelliSense 顯示為擴充方法(藍色下箭頭圖示)
var age = reader.GetInt32("Age");
Visual Studio 會在成員清單中以特殊圖示標示擴充方法,並自動帶入 this 參數。
擴充 IDataReader 介面,所有實作類別(SqlDataReader、OracleDataReader 等)自動獲得擴充方法:
public static T GetValue(this IDataReader dr, string name)
{
var ordinal = dr.GetOrdinal(name);
return (T)dr.GetValue(ordinal);
}
// 使用
var id = reader.GetValue("Id");
var email = reader.GetValue("Email");
public static class ObjectExtensions
{
public static bool IsIn(this object item, IEnumerable collection)
{
foreach (var elem in collection)
if (Equals(item, elem)) return true;
return false;
}
public static bool IsEmail(this string text)
=> Regex.IsMatch(text, @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$");
}
所有型別(含實值型別經裝箱)皆可呼叫:
if (userInput.IsEmail()) { ... }
if (selectedItem.IsIn(validOptions)) { ... }
using 其命名空間時可見,避免污染全域 IntelliSense*.Extensions 命名空間LINQ 標準查詢運算子(Where、Select、GroupBy...)本質都是擴充 IEnumerable<T> 的靜態方法。理解擴充方法機制,有助於深入掌握 LINQ 延遲執行、串流處理等核心概念。
| 建議 | 說明 |
|---|---|
| 勿濫用 | 核心領域邏輯應放在型別內部,擴充方法適合跨領域關注點(序列化、驗證、轉換) |
| 避免擴充基礎型別 | 擴充 object、string 會出現在所有 IntelliSense,造成干擾 |
| 保持純函數特性 | 擴充方法最好無副作用、不依賴外部狀態,易於測試與推理 |
| 注意 null 檢查 | this T source 可能為 null,方法內需防禦性檢查 |