简体   繁体   English

C#代表,为什么我们需要它们?

[英]C# delegates and why do we need them?

I am trying to understand "callback pattern". 我试图理解“回调模式”。 Every answer says that this is done with delegates (which I know them). 每个答案都说这是由代表们完成的(我知道他们)。 But the codes on the answers are something like that: 但答案的代码是这样的:

public delegate void Callback(string result);

public void Test()
{
    CallBack callback = CallbackFunction; 
    DoWork(callback);
}

public void DoWork(CallBack callback)
{
    callback("Hello world");
}

public void CallbackFunction(string result)
{
    Console.WriteLine(result);
}

I really don't understand, why we need delegate for this? 我真的不明白,为什么我们需要代表呢? We can do this in this way too? 我们也可以这样做吗?

public void Test()
{
    DoWork();
}

public void DoWork()
{
    CallbackFunction("Hello world");
}

public void CallbackFunction(string result)
{
    Console.WriteLine(result);
}

Besides that, for example in Java, a callback means a real "return" to the main program's "particular function" after an event. 除此之外,例如在Java中,回调意味着在事件之后真正“返回”主程序的“特定功能”。 But when we use delegates, isn't this just calling another method? 但是当我们使用委托时,这不仅仅是调用另一种方法吗?

How can we make a callback that finally calls an OnFail() method on fail, and OnSuccess() method on success. 我们怎样才能使一个回调最后调用的OnFail()上fail方法,和OnSuccess()上的成功方法。 I am really confused. 我真的很困惑。 Can somebody help me to understand this? 有人可以帮我理解这个吗?

A delegate safely encapsulates a method, a kind of a template to a function in its signature. 委托安全地将方法,一种模板封装到其签名中的函数中。 Sometimes it is easy to think it is a pointer to a function. 有时很容易认为它是指向函数的指针。

In your sample, the CallbackFunction can be setted to Callback because both in its definition takes just a string argument. 在您的示例中, CallbackFunction可以设置为Callback因为它的定义只接受一个字符串参数。

You could use Action and Func instead of delegate . 您可以使用ActionFunc代替delegate The difference between them is that an Action does not return something and Func does. 它们之间的区别在于Action不会返回某些内容而Func会返回。 For sample: 样品:

public void Test(Action success, Action<Exception> error)
{
    try
    {
        // perform some task
        success();
    }
    catch (Exception ex)
    {
        error(ex);
    }
}

And use it: 并使用它:

Test(() => { Console.WriteLine("Success"); },
     (ex) => { Console.WriteLine($"Error: {ex.Message}"); });

the generic option of an Action is the type of the arguments you can pas to this method. Action的泛型选项是您可以传递给此方法的参数的类型。 On the sample, Exception is a argument which is passed to error Action . 在示例中, Exception是一个传递给error Action的参数。 The same is valid for a Func<> but the last type of a Func is the result type. 这对于Func<>是有效的,但最后一种类型的Func是结果类型。

Why do we need delegates? 为什么我们需要代表?

Because in many programs, you need the ability to abstract the concept of a method. 因为在许多程序中,您需要能够抽象出方法的概念。 One reason is events, another is a set of methods like this: 一个原因是事件,另一个是一组这样的方法:

public void DoWork(Action completeCallback)
{
    ... //Do Stuff
    completeCallback();
}

public void FirstMainMethod()
{
     DoWork(() => Console.WriteLine("First callback");
}

public void SecondMainMethod()
{
     DoWork(() => Console.WriteLine("Second callback");
}

In other words, different parts of my code need to have a different method run on completion, so I pass it in (I can't use a direct call). 换句话说,我的代码的不同部分需要在完成时运行不同的方法,所以我传入它(我不能使用直接调用)。 The delegate abstraction allows this. 委托抽象允许这样做。 Also note that the idea of a "completion" callback in .NET is pretty silly, you almost never need it. 另请注意,.NET中“完成”回调的想法非常愚蠢,您几乎不需要它。 You will use delegates for this general idea all the time though. 您将使用代表这个总体思路,虽然所有的时间

How can we make a callback that finally calls an OnFail() method on fail, and OnSuccess() method on success? 我们如何进行最终在失败时调用OnFail()方法的回调,以及成功时调用OnSuccess()方法?

You can do this pretty easily. 你可以很容易地做到这一点。 You can even make a somewhat generic one (not sure if you would ever want to mind you, but the following code works): 你甚至可以制作一个通用的(不确定你是否想要介意你,但以下代码有效):

public void SuccessFailHelper(Func<bool> work, Action success, Action failure)
{
   if (work())
      success();
   else
      failure();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM