0

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;
    }
1
  • No, it is not possible to create a method that accespts a func of any arbitrary number of parameters such as Action<T>, ActionT1, T2, ...>. Commented Apr 20, 2016 at 9:05

1 Answer 1

4

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);
Sign up to request clarification or add additional context in comments.

3 Comments

I guess OP needs to pass any arbitrary method with any arbitrary number of parameters, not only one. So Also this should work for him: (x) => x.DoSomething(myArgument, anotherArgument));
@HimBromBeere Which you wrap in a delegate that has zero arguments - exactly what I suggested in the first place. Either the method must know about the arguments, and then there's no point in allowing delegates that don't fit the signature, or it doesn't care about the arguments, and then it just takes Action.
Yes this is what i was looking for now i can pass methods to ShowCustomDialog and it doesnt have to know anything about what kind of method it is.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.