在 C# 中实现回调

Bru*_*son 3 c#

C# 新手并试图弄清楚如何进行回调。(如果这确实是回调)

我有一些格式为 ..

        connector.Subscribe(data1, data2, (element, value) =>
        {
            Log($"{element.Name}: {value}");
        });
Run Code Online (Sandbox Code Playgroud)

我想让它们都使用相同的功能,而不是将代码添加到每个例如

    public void somefunction(element, value)
    {
        Log($"{element.Name}: {value}");
    }

    connector.Subscribe(data1, data2, somefunction);
Run Code Online (Sandbox Code Playgroud)

老实说,我不知道从哪里开始,所以感谢任何帮助

Oli*_*bes 8

声明一个签名与函数签名相匹配的委托。例如:

public delegate void MyCallback(string name, int value);
Run Code Online (Sandbox Code Playgroud)

然后声明Subscribe为

public void Subscribe(object data1, object data2, MyCallback myCallback)
{
}
Run Code Online (Sandbox Code Playgroud)

然后你可以做你要求的:

connector.Subscribe(data1, data2, somefunction);
Run Code Online (Sandbox Code Playgroud)

注意somefunction这里必须不带参数大括号写。


另一种解决问题的方法是声明一个合适的接口。例如一个ILogger接口。您将传递一个记录器对象,而不是传递记录器函数。

这有以下优点:

  • 你可以注入一个记录器。请参阅依赖注入(维基百科)。
  • 您可以使用IoC 容器 (TutorialsTeacher)将记录器配置为在中心位置使用。
  • 您可以创建一个包装对象,实现ILogger它本身ILogger在构造函数中接受对象列表。例如,您可以将控制台记录器和文件记录器传递给它。呼叫站点不需要知道您希望所有内容都被记录两次。
  • 如果您不想记录,您可以使用虚拟记录器什么也不做(同样不更改调用站点)。

换句话说。接口比委托更灵活。

  • 是的,你可以这么做。委托的优点是您可以为其指定一个名称(希望比我的示例中的“MyCallback”更好),并且您还可以命名参数。 (2认同)