使用 Action 和回調來實現跟 Func相同的效果

展示如何用 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,這邊就是看個別開發人員的習慣。

Tags: