创建一个类似Action.Invoke的方法



我试图写一个简单的方法,使代码更容易读。我正在写一个部分,我有异步任务,所以我使用的动作作为我的方法的参数,给可能性获得回调,当方法已经完成。

总之,我的签名总是这样的:

public void myAsyncMethod(...params..., Action<other params> onFinish = null)

我使用默认的Action为null只是为了给库用户提供更多的灵活性,但在我的实现中,我总是写这段代码:

if (onFinish != null)
{
UnityMainThreadDispatcher.Instance().Enqueue(
() => onFinish(other params)
);
}

这是因为在unity中,我允许在主线程上启动Action,以防用户需要与图形周期交互。我的想法是:我能把这段代码放在一个方法中,让方法实现更容易读吗?如果能像这样调用它,那就太好了:

onFinish?.InvokeOnMainThread(other params);

有点像Action?调用的方法。所以我在c#中做了一些关于扩展方法,动作和泛型的搜索,但我无法掌握用泛型构建一个方法来做我想要达到的目标。我真的不知道该搜索什么来达到我的目标,我四处看了看,但可能我不够好,不能把这些概念放在一起来达到我的目标。

到目前为止,我认为这样的事情(不工作):

public static void InvokeOnMainThread(this Action<T1, T2>, T1 t1, T2 t2){ ... }
public static void InvokeOnMainThread<Action, T1, T2>(Action<T1, T2>, T1 t1, T2 t2){ ... }

我只使用2个参数的Action,因为在我的情况下是最常见的,但我需要使用0到4个参数的相同调用(但我认为,当我能掌握这个概念时,它将很容易扩展,或者至少我可以根据我需要的参数数量复制它)。

您需要为0-4个可能的参数创建单独的扩展方法,如下所示:

public static partial class UnityExtensions
{
public static void InvokeOnMainThread(this Action onFinish)
{
if (onFinish != null) // Or throw ArgumentNullException() if you prefer
UnityMainThreadDispatcher.Instance().Enqueue(() => onFinish());
}

public static void InvokeOnMainThread<T1>(this Action<T1> onFinish, T1 t1)
{
if (onFinish != null)
UnityMainThreadDispatcher.Instance().Enqueue(() => onFinish(t1));
}

public static void InvokeOnMainThread<T1, T2>(this Action<T1, T2> onFinish, T1 t1, T2 t2)
{
if (onFinish != null)
UnityMainThreadDispatcher.Instance().Enqueue(() => onFinish(t1, t2));
}

public static void InvokeOnMainThread<T1, T2, T3>(this Action<T1, T2, T3> onFinish, T1 t1, T2 t2, T3 t3)
{
if (onFinish != null)
UnityMainThreadDispatcher.Instance().Enqueue(() => onFinish(t1, t2, t3));
}

public static void InvokeOnMainThread<T1, T2, T3, T4>(this Action<T1, T2, T3, T4> onFinish, T1 t1, T2 t2, T3 t3, T4 t4)
{
if (onFinish != null)
UnityMainThreadDispatcher.Instance().Enqueue(() => onFinish(t1, t2, t3, t4));
}
}

然后你可以这样做:

onFinish?.InvokeOnMainThread(param1, param2); // Or however many parameters you have.

中所述,我可以有可变数量的泛型参数吗?, c#不允许可变数量的泛型参数。这就是为什么每个支持的参数数量都有不同的Tuple.Create<>()方法。

最新更新