ภาพรวม
Extension Methods เป็นเมธอดแบบ Static ที่เรียกใช้ได้เหมือน Instance Method ของชนิดข้อมูลที่ขยาย (Extended Type) ช่วยให้เพิ่มฟังก์ชันให้กับ Type ที่มีอยู่แล้ว (Built-in types, Library types, Sealed classes) โดยไม่ต้องสร้าง Subclass, Recompile, หรือแก้ไขโค้ดต้นฉบับ
กฎสำคัญ
- ต้องอยู่ใน Static Class
- เมธอดต้องเป็น Static
- พารามิเตอร์แรกต้องมีคีย์เวิร์ด
thisนำหน้าชนิดที่ขยาย - Namespace ของ Extension Class ต้องถูก
usingเข้ามา
ตัวอย่าง Extension Method
public static class StringExtensions
{
// Extension method สำหรับ string: แปลงเป็น int
public static int ToInt(this string str)
{
return int.Parse(str);
}
// Extension method เพิ่มเติม: ตรวจสอบว่ามีตัวอักษรพิมพ์ใหญ่หรือไม่
public static bool HasUpperCase(this string str)
{
return str.Any(char.IsUpper);
}
// Extension method กับพารามิเตอร์เพิ่มเติม
public static string Repeat(this string str, int count)
{
return string.Concat(Enumerable.Repeat(str, count));
}
}ตัวอย่างการใช้งาน
using System;
using System.Linq; // จำเป็นสำหรับ Enumerable.Repeat
namespace Program
{
class Program
{
static void Main(string[] args)
{
string str1 = "565";
// เรียกเหมือน Instance Method
int n = str1.ToInt();
Console.WriteLine("Result: {0}", n); // 565
// ใช้ Extension อื่นๆ
Console.WriteLine("Has Upper: " + "hello".HasUpperCase()); // False
Console.WriteLine("Has Upper: " + "Hello".HasUpperCase()); // True
Console.WriteLine("Repeat: " + "Ha".Repeat(3)); // HaHaHa
// Intellisense จะแสดง Extension Methods พร้อมไอคอนลูกศรลง (↓)
}
}
}ผลลัพธ์
Result: 565 Has Upper: False Has Upper: True Repeat: HaHaHa
Extension Methods ยอดนิยมใน .NET Framework (Built-in)
หลายเมธอดใน LINQ เป็น Extension Methods ของ IEnumerable<T>:
.Where(),.Select(),.OrderBy(),.GroupBy().ToList(),.ToArray(),.ToDictionary().First(),.Single(),.Any(),.All()
ข้อสังเกตและ Best Practices
- ไม่สามารถ Override เมธอด Instance ได้ - Instance method มีความสำคัญกว่าเสมอ
- ไม่เข้าถึง private members ของชนิดที่ขยาย (เพราะเป็น static method ภายนอก)
- Null safety: Extension method เรียกได้แม้ Instance เป็น null → ควรตรวจสอบ null ภายใน
- Naming: วางใน Namespace แยก (เช่น
MyProject.Extensions) เพื่อไม่ให้ปนเป้อน - ใช้เพื่อ: เพิ่ม Helper methods, Fluent API, Domain-specific operations
- หลีกเลี่ยง: การเพิ่มเมธอดมากเกินไปให้ Type เดียว (Pollution), Business logic ที่ซับซ้อน
ตัวอย่าง Null-safe Extension
public static class StringExtensions
{
public static bool IsNullOrEmpty(this string str)
{
return string.IsNullOrEmpty(str); // เรียกได้แม้ str == null
}
public static string SafeTrim(this string str)
{
return str?.Trim() ?? string.Empty;
}
}