前篇已經聊過關於 Extension members 的一些基本操作,這裡補充一些前篇沒提到的部分。
運算子的擴充
這裡所謂的運算子是排除了 C# 14 新增的複合指派運算子,專指原來定義在型別內以靜態成員宣告並且是可以多載 (overloading)的運算子,如加減乘除這一類的;額外的限制是目前為止還無法支援顯式與隱式轉換運算子。
有了這個基本概念,以下就用為 Vector2 新增遞增與遞減運算子為例:
public static class Vector2Extensions
{
private static readonly Vector2 _one = new Vector2(1, 1);
extension(Vector2 source)
{
public static Vector2 operator ++(Vector2 vector)
{
return vector + _one;
}
public static Vector2 operator --(Vector2 vector)
{
return vector - _one;
}
}
}除了多出個 extension 區塊這檔事,方法的宣告方式其實與在型別內部多載運算子是一樣的。
泛型處理
在 extension 宣告的泛型接收器必須是開放型別參數(open type),不可以是個封閉型別(closed type),例如以下是符合規則的宣告:
public static class MyExtensions
{
extension<T>(T source)
{
public IEnumerable<T> Repeat(int count)
{
return Enumerable.Repeat(source, count);
}
}
}以下的程式碼使用了封閉型別則是不符合規定的宣告方式:
// 錯誤:封閉的泛型型別
public static class WrongExtensions
{
// 不能這樣寫 - List<int> 是封閉型別
extension(List<int> source) // 編譯錯誤
{
public void DoSomething() { }
}
// 不能這樣寫 - Dictionary<string, int> 是封閉型別
extension(Dictionary<string, int> dict) // 編譯錯誤
{
public void Process() { }
}
}
public static class WrongExtensions
{
// 不能這樣寫 - extension 泛型參數中混用開放與封閉型別
extension<string, T>(Dictionary<string, T> dict) // 錯誤!
{
public void AddItem(string key, T value) { }
}
}