- Home /
How to declare an Action with return type other than void?
I'm making a EventManager ActionScript-like.
So far I have something like this:
public class EventManager
{
private static Dictionary<string, List<Action>> m_EventDictionary = new Dictionary<string, List<Action>>();
public static bool AddEventListener(string eventType, Action callback)
{
if (!m_EventDictionary.ContainsKey(eventType))
{
m_EventDictionary[eventType] = new List<Action>();
}
if (!m_EventDictionary[eventType].Contains(callback))
{
m_EventDictionary[eventType].Add(callback);
return true;
}
return false;
}
public static bool RemoveEventListener(string eventType, Action callback)
{
if (m_EventDictionary.ContainsKey(eventType))
{
return m_EventDictionary[eventType].Remove(callback);
}
return false;
}
public static void DispatchEvent(string eventType, CustomEvent e = null)
{
List<Action> callbacks = new List<Action>();
if (m_EventDictionary.ContainsKey(eventType))
{
for (int i = 0; i < m_EventDictionary[eventType].Count; i++)
{
callbacks.Add(m_EventDictionary[eventType][i]);
}
}
for (int i = 0; i < callbacks.Count; i++)
{
callbacks[i]();
}
}
}
.
It's working so far but it only works with void return type methods. I'd like to add some IEnumerator return type methods (for coroutines) but Action only accept void return type. Is there a way I can do this? I can change Action for another type if I have to.
Thanks
Nitpicking, but is there a reason you produce a new List whenever you call DispatchEvent
? You already have that string mapped to a list of Actions, why not use that?
Answer by Bunny83 · Apr 30, 2018 at 09:32 PM
The mscorlib.dll predefines several delegate types. Generally they can be divided into two categories:
Actions
Function
There are two non generic delegate types, Action
and Func
and several generic versions. While Action
is just a delegate with no parameters and no return type, Func is a function with no parameters and object
as return type.
The generic variants allow you to actually specify the types of the parameter(s) and the type of the return type in case of Func<>
.
The generic Action delegates comes with either one, or multiple parameters. Action<T>
, Action<T0, T1>
, ...
The generic Func delegates comes with either none, one or multiple parameters. The last generic type parameter is always the return type Func<TRes>
, Func<T, TRes>
, Func<T0, T1, TRes>
Just as example this delegate type:
public Func<int, string, bool> myFunc;
is the same as this
public delegate bool MyFuncType(int t0, string t1);
public MyFuncType myFunc;
and this would be compatible with a method like
bool SomeMethod(int someInt, string str)
So you can do
myFunc = SomeMethod;
myFunc(42, "Hello world");
Answer by MacDx · Apr 30, 2018 at 07:35 PM
By its definition, Action only encapsulate methods that do not return a value.
From MSDN docs:
Encapsulates a method that has no parameters and does not return a value.
Action is just a delegate tho. You can define your own delegate type and use that instead. Something like this:
//Whatever return type you want in this case I'll simply use a bool
public delegate bool EventCallback();
Then use that instead of Action. Although I'm having trouble understanding what you would use this for, to do some logic on your DispatchEvent method?
Func did the trick.
I was trying to call every callback for that "eventType", waiting for all to conclude and then proceed with my Code. It was something like this:
yield return StartCoroutine(Event$$anonymous$$anager.DispatchEvent(eventType));
//do something after all coroutine concluded
Your answer
![](https://koobas.hobune.stream/wayback/20220612161807im_/https://answers.unity.com/themes/thub/images/avi.jpg)