[英]C# Pass Method as parameter with different parameters with Action and Func delegates
[英]Unity C# Action Delegates - How to Create List<Action> with different parameter types?
我希望在這里得到一些幫助(我是C#
和Unity
的新手)。
我想創建一個Action
List
,我最終可以在OnDestroy
生命周期方法調用期間循環並清除/取消它。
Anyhoo,我將在下面標記我想要實現的目標以及錯誤是什么:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Game : MonoBehaviour
{
// Action delegate
public static Action OnEvent1;
public static Action<int> OnEvent2;
public static Action<Vector2> OnEvent3;
public static Action<Vector2> OnEvent4;
public static Action OnEvent5;
public static Action<bool> OnEvent6;
private List<Action> ActionListToClear = new List<Action>() {
OnEvent1, // all good
OnEvent2, // Error as Action<int> is not Action
OnEvent3, // Error as Action<Vector2> is not Action
OnEvent4, // Error as Action<Vector2> is not Action
OnEvent5, // all good
OnEvent6 // Error as Action<bool> is not Action
};
....
private void OnDestroy()
{
foreach (Action action in ActionListToClear )
{
action = null;
}
}
};
我還嘗試在List
中實現泛型類型:
private List<Action<T>> ActionList = new List<Action<T>() { OnEvent1, OnEvent2... etc. };
但這會導致:
The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)
有誰知道創建具有不同Action
類型的List<Action>
的最佳方法? 即帶參數和不帶參數? 謝謝!
我要試一試。 您問題下的所有評論都很棒。 你必須以更加面向對象的方式思考。 這里有一個關於如何完成你想要的東西的想法,也許會讓你跳出框框思考更多。 無論如何,我並不是說你應該這樣做。 只是對您可以使用的東西的想法。
所以你定義了一個接口,這是所有“Action”對象的共同點。 你在你的問題中說你只是想要一種“銷毀”它們的方法,所以我們將強制實現它的任何東西也實現Destory()
public interface IAction
{
void Destroy();
}
現在我們創建一個“基礎”動作,它可以執行 1 個參數,該參數具有Destroy
應該執行的默認實現:
public abstract class BaseAction<T> : IAction
{
public Action<T> Action { get; protected set; }
public virtual void Destroy()
{
Action = null;
}
}
現在我們創建另一個“基礎”動作,它可以執行 0 個參數,該動作具有Destroy
應該執行的默認實現:
public abstract class BaseAction : IAction
{
public Action Action { get; protected set; }
public virtual void Destroy()
{
Action = null;
}
}
然后我們創建我們的實際事件:
public class Event6 : BaseAction<bool>
{
public Event6()
{
Action = new Action<bool>(x =>
Console.WriteLine($"I just executed Event 6 with {x}"));
}
}
public class Event7 : BaseAction
{
public Event7()
{
Action = new Action(() =>
Console.WriteLine("I just executed Event 7"));
}
public override void Destroy()
{
// do something special here
base.Destroy();
}
}
public class Event8 : BaseAction<int>
{
public Event8()
{
Action = new Action<int>(x =>
Console.WriteLine($"I just executed Event 8 with {x}"));
}
}
現在我們可以創建我們想要的所有事件
private Event6 _ev6 = new Event6();
private Event7 _ev7 = new Event7();
private Event8 _ev8 = new Event8();
public void Main(string[] args)
{
// how you'd call the actions:
_ev7.Action.Invoke();
_ev6.Action.Invoke(true);
// now remember, the `Action` member could be null if they were Destroyed... see below
// you can then create an array of them because they all have "IAction" in common
var lst = new List<IAction> { _ev6, _ev7, _ev8 };
// you can also iterate over them and destroy them.
lst.ForEach(x => x.Destroy());
}
正如幾位好心的海報所指出的那樣,將我的所有Actions
添加到List
以在OnDestroy
期間循環的方法可能會使問題過於復雜。
相反,以下方法可以解決問題:
private void OnDestroy()
{
OnEvent1 = null;
OnEvent2 = null;
OnEvent3 = null;
...etc.
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.