3

I have a class that currently looks like this:

public Action<string> Callback { get; set; }

public void function(string, Action<string> callback =null)
{
   if (callback != null) this.Callback = callback;
   //do something
}

Now what I want is to take an optional parameter like:

public Action<optional, string> Callback { get; set; }

I tried:

public Action<int optional = 0, string> Callback { get; set; }

it does not work.

Is there any way to allow Action<...> take one optional parameter?

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
user2846737
  • 201
  • 3
  • 5
  • 13
  • 2
    http://stackoverflow.com/questions/7690482/parameter-actiont1-t2-t3-in-which-t3-can-be-optional – Habib Oct 25 '13 at 18:49
  • It's unlikely this syntax exists. And how exactly would an optional parameter in the return value work? – Zong Oct 25 '13 at 18:49

1 Answers1

11

You can't do this with a System.Action<T1, T2>, but you could define your own delegate type like this:

delegate void CustomAction(string str, int optional = 0);

And then use it like this:

CustomAction action = (x, y) => Console.WriteLine(x, y);
action("optional = {0}");    // optional = 0
action("optional = {0}", 1); // optional = 1

Notice a few things about this, though.

  1. Just like in normal methods, a required parameter cannot come after an optional parameter, so I had to reverse the order of the parameters here.
  2. The default value is specified when you define the delegate, not where you declare an instance of the variable.
  3. You could make this delegate generic, but most likely, you'd only be able to use default(T2) for the default value, like this:

    delegate void CustomAction<T1, T2>(T1 str, T2 optional = default(T2));
    CustomAction<string, int> action = (x, y) => Console.WriteLine(x, y);
    
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • 2
    There is a limitation with the generic approach, in that you always have to provide a Type for the optional argument, even when you don't need it. To make it truly optional, you'd have to declare multiple delegates for each use case, as such: `delegate void CustomAction(T1 first);` `delegate void CustomAction(T1 first, T2 second);` A quick look at the framework implementation of Action<...> shows us this is exactly how our friends at Microsoft do it. – Dimitri Troncquo Apr 19 '18 at 08:11