這篇在講什麼
Extension Method 的價值不在於讓程式跑更快,而是在於把那些重複、零碎、但非常常用的操作收斂成更好讀的 API。
在 Unity 裡這件事尤其常見,因為像 Vector2、Vector3、Color、Transform 這些型別,經常會有一堆很像的小操作。
它在解什麼問題
例如你想把物件位置的 z 增加 10,直覺可能會寫:
transform.position.z += 10;
但這樣不行,因為 transform.position 回傳的是 Vector3 的值複本,不是可直接原地修改的引用。
最後常會被迫寫成:
transform.position = new Vector3(
transform.position.x,
transform.position.y,
transform.position.z + 10);
這不是不能用,但很吵,也容易在專案裡一再重複。
Extension Method 的基本寫法
定義 extension method 有三個重點:
- 放在
static類別裡 - 方法本身也要是
static - 第一個參數前面加上
this
例如:
public static class VectorExtensions
{
public static Vector3 WithZ(this Vector3 value, float z)
{
value.z = z;
return value;
}
}
之後就可以這樣用:
transform.position = transform.position.WithZ(transform.position.z + 10);
為什麼這樣比直接 new 更好
好處通常有幾個:
- 減少重複樣板碼
- 讓呼叫端更接近語意表達
- 同類操作可以集中管理
當某個修改動作在很多地方都會出現時,這種封裝的累積效果很明顯。
Unity 裡哪些型別很適合擴充
常見的目標包括:
Vector2Vector3ColorQuaternionTransformGameObject
例如:
public static Vector3 AddY(this Vector3 value, float delta)
{
value.y += delta;
return value;
}
public static Color WithAlpha(this Color value, float alpha)
{
value.a = alpha;
return value;
}
用在值型別時要注意什麼
像 Vector2、Vector3、Color 這些都是 struct,所以 extension method 拿到的是複本。
這代表:
- 你修改的是副本
- 必須把結果回傳出去
- 呼叫端也要把回傳值接回去
真正有用的是這種寫法:
transform.position = transform.position.WithZ(10f);
而不是:
transform.position.WithZ(10f);
後者就算語法成立,結果也不會留在 transform.position 上。
命名最好直接表達意圖
像 WithZ(...)、AddY(...)、WithAlpha(...) 這種命名,通常會比過短的方法名更清楚。
一眼就能知道這個方法是在:
- 指定某個欄位
- 還是做增量修改
可讀性通常比省幾個字更重要。
我自己的整理
Extension Method 很適合拿來做「高頻、小型、語意明確」的操作封裝。
它最適合改善的是:
- API 手感
- 可讀性
- 重複樣板碼
它不會神奇地優化效能,但很能優化日常開發體驗。
先記住的重點
- Extension Method 是可讀性與封裝工具,不是效能工具
- 第一個參數要用
this指定被擴充的型別 - 面對 struct 時,記得要把回傳值接回去
- Unity 裡的向量、顏色、Transform 都很適合做這類小擴充