展示如何用 Action<T>
和回調來實現帶有返回值的功能
以最少知識原則,能簡單就維持簡單,能用一種方式實現多數情況,那就一以貫之。
假設我們有一個場景,玩家進入觸發區域並嘗試撿起物品,我們希望在處理完成後得到結果,這裡的結果由回調函數返回。
使用 Func<T>
的範例
首先,使用 Func<T>
的例子:
using UnityEngine;
using System;
public class PickupFuncExample : MonoBehaviour
{
// 定義一個 Func,接受兩個參數並返回一個布爾值
public Func<string, int, bool> OnItemPickup;
private void Start()
{
// 設置回調方法
OnItemPickup += TryPickupItem;
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
// 當玩家進入觸發區域時,嘗試撿起物品
bool success = OnItemPickup?.Invoke("Health Potion", 1) ?? false;
if (success)
{
Debug.Log("Item successfully picked up.");
}
else
{
Debug.Log("Failed to pick up item.");
}
}
}
// 回調方法,嘗試撿起物品
private bool TryPickupItem(string itemName, int quantity)
{
// 實際的物品撿起邏輯,例如檢查背包空間等
Debug.Log($"Trying to pick up {quantity} of {itemName}.");
return true; // 假設物品總是能成功撿起
}
}
使用 Action<T>
和回調的範例
接下來,使用 Action<T>
和回調函數來實現相同的功能:
using UnityEngine;
using System;
public class PickupActionExample : MonoBehaviour
{
// 定義一個 Action,接受兩個參數和一個回調
public Action<string, int, Action<bool>> OnItemPickup;
private void Start()
{
// 設置回調方法
OnItemPickup += (itemName, quantity, callback) => {
bool success = TryPickupItem(itemName, quantity);
callback?.Invoke(success);
};
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
// 當玩家進入觸發區域時,嘗試撿起物品
OnItemPickup?.Invoke("Health Potion", 1, (success) => {
if (success)
{
Debug.Log("Item successfully picked up.");
}
else
{
Debug.Log("Failed to pick up item.");
}
});
}
}
// 回調方法,嘗試撿起物品
private bool TryPickupItem(string itemName, int quantity)
{
// 實際的物品撿起邏輯,例如檢查背包空間等
Debug.Log($"Trying to pick up {quantity} of {itemName}.");
return true; // 假設物品總是能成功撿起
}
}
總結
Func<T>
:適用於需要直接返回結果的情況,使用起來較直接。Action<T>
和回調:雖然主要用於沒有返回值的情況,但可以通過引入回調函數來模擬返回值的效果。這種方法在某些情況下可以提供更多的靈活性,例如在處理異步操作或需要在操作完成後進行多步處理時。
因為Action的靈活性,還有相較於Func,Action框出了相關執行功能的範圍,所以我特別喜歡Action,這邊就是看個別開發人員的習慣。