Search code examples
c#methodslambdadelegates

C# lambda as parameter to method


In C# is it possible to have a method accepting a delegate that has zero, 1 or many parameters?

In the method below i want to be able to do al kind of things when i click yes on the dialog box. I used a delegate for this but currently it only accepts methods without parameters.

There are probably multiple ways to do this like passing a generic class containing the parameters but what is the best way to do this? Does C# provide something out of the box to do this in a elegant way?

    public static bool ShowCustomDialog(string message, 
                                        string caption, 
                                        MessageBoxButtons buttons,
                                        XafApplication application, 
                                        Action onYes = null)
    {
        Messaging messageBox = new Messaging(application);
        var dialogResult = messageBox.GetUserChoice(message, caption, buttons);
        switch (dialogResult)
        {
            case DialogResult.Yes:
                onYes?.Invoke();
                break;
        }
        return false;
    }

Solution

  • To address your question directly, that's why you use lambdas:

    ShowCustomDialog("Hi!", "Greeting", MessageBoxButtons.YesNo, 
                     () => DoSomething(myArgument, anotherArgument));
    

    This is at the core of techniques like dependency injection - the ShowCustomDialog method shouldn't know anything about the action except for the fact that it's something that doesn't require input from the ShowCustomDialog method itself. If ShowCustomDialog had to pass some argument, you'd use Action<SomeType> instead of Action.

    Under the covers, the compiler creates a class that contains the arguments to be passed, and creates a delegate that Targets an instance of that class. So it's (mostly) equivalent to manually writing something like this:

    class HelperForTwoArguments
    {
      bool arg1;
      string arg2;
    
      public HelperForTwoArguments(bool arg1, string arg2)
      {
        this.arg1 = arg1;
        this.arg2 = arg2;
      }
    
      public void Invoke()
      {
        DoSomething(arg1, arg2);
      }
    }
    
    // ...
    
    ShowCustomDialog("Hi!", "Greeting", MessageBoxButtons.YesNo,
                     new HelperForTwoArguments(myArgument, anotherArgument).Invoke);
    

    This capability has been in the .NET framework since the very beginning, it just got much easier to use with anonymous delegates and especially lambdas.

    However, I have to say I don't see any point to your "helper" method at all. How is it different from doing something like this?

    if (ShowCustomDialog("Hi!", "Greeting", MessageBoxButtons.YesNo))
      DoSomething(myArgument, anotherArgument);