接受任意类型的回调

本文关键字:回调 类型 任意 | 更新日期: 2023-09-27 18:31:01

我正在尝试在C#中实现一个 JsonRpc 客户端类,每当响应 JsonRpc 时,它都会执行给定的 method/delegate/callback(以解释为什么我需要我要问的东西)。

为此,我想要一个方法来注册任意类型的回调(任意参数列表)。每当响应到达时,都会调用/评估此回调。这意味着在注册时,无论回调是什么,它都会被接受,并且在执行时,一旦使用响应的类型进行检查,其类型可能会导致异常。

我见过像这样实现类似概念的代码:

//Defining a delegate based on a method signature
Delegate d = Delegate.CreateDelegate(delegate_type, context, methodInfo);
//Executing the delegate when response arrives
d.DynamicInvoke(parameters);

如果我要实现相同的方法,我需要做的就是接受用于注册回调的 Delegate 类型的参数。但这对我不起作用,因为我希望注册回调比创建其Delegate要容易得多(需要十几行才能想出一个方法的Delegate)。

最后,我的问题来了:

您将如何在C#中实现注册任意类型的回调?

[更新]

或者也许有人可以想出一种简单的方法来创建方法的Delegate!?

接受任意类型的回调

我不确定你说消费者需要"创造Delegates"是什么意思。这是我想出的一个例子,它工作得很好,对于你的方法的消费者来说似乎并不难做到。

private static void HigherOrderFoo(Delegate foo)
{
    var returnVal = foo.DynamicInvoke(null);
}
private static void Bar()
{
    HigherOrderFoo((Func<int>)(() => 10));
}

同样,lambda 函数也可以是一个方法组,将其转换为委托类型也可以。

private static void HigherOrderFoo(Delegate foo)
{
    var returnVal = foo.DynamicInvoke(null);
}
private static void Bar()
{
    HigherOrderFoo((Func<int>)Baz);
}
private static int Baz()
{
    return 10;
}

此外,这是 Jon Skeet 的一个很好的答案,它解释了为什么您需要将参数转换为实际的委托类型才能将其转换为Delegate

编辑:如果您作为参数传入的方法有自己的参数,则可以使用 params 关键字将参数传递给HigherOrderFoo

private static void HigherOrderFoo(Delegate foo, params object[] list)
{
    var bar = foo.DynamicInvoke(list);
}
private static void Bar()
{ 
    HigherOrderFoo((Func<int, int>)Baz, 10);
}
private static int Baz(int val)
{
    return val * val;
}