19

I have the following method in an assembly:

public string dostuff(string foo, object bar = null) { /* ... */ }

I use it as a callback, so a reference to it is passed to another assembly as such:

Func<string, object, string> dostuff

Now in the original form, I can call it without specifying that second argument, which defaults to null. But when I use it as a callback in that second assembly, I must specify that second argument.

What syntax allows me to ignore that second argument?

h bob
  • 3,610
  • 3
  • 35
  • 51
  • possible duplicate of [Using C# delegates with methods with optional parameters](http://stackoverflow.com/questions/5729154/using-c-sharp-delegates-with-methods-with-optional-parameters) – TyCobb Jan 28 '15 at 18:51

2 Answers2

18

You'll need to create a new method that accepts only one argument, and that passes the default value for the second argument. You could do this with a lambda, rather than creating a new named method, if you wanted:

Func<string, string> doStuffDelegate = s => dostuff(s);

The other option would be to use a delegate who's signature has an optional second argument, instead of using Func, in which case your method's signature would match:

public delegate string Foo(string foo, object bar = null);

You could assign dostuff to a delegate of type Foo directly, and you would be able to specify only a single parameter when invoking that delegate.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • So if there are two assemblies and one has a callback into the other, then that delegate signature is contained in the one receiving the callback reference? In the one that declares the actual callback function, it must match that signature. – h bob Jan 28 '15 at 18:56
  • when you use optional argument in delegates signature, its Invoke method will also have an optional parameter in its signature, right? – Selman Genç Jan 28 '15 at 19:01
  • One more thing, for your lambda option, where does it go - in the assembly which receives or declares the callback function? – h bob Jan 28 '15 at 19:10
  • Neither :) I'm obvisouly getting the syntax wrong... I'll figure it out – h bob Jan 28 '15 at 19:12
  • Ah! I didn't understand what you meant initially... you meant method overloading the callback, now I get it! :) – h bob Jan 28 '15 at 19:14
  • @hbob That's not actually what I was suggesting, but that would work to, if the method exposing the callback might have a value to pass in, but doesn't need to. – Servy Jan 28 '15 at 19:17
3

You can't do this, simply because optional arguments are syntactic sugars and can be only used if you are calling the method directly. When you call the method like this:

dostuff(foo);

Compiler translates it into:

dostuff(foo, null);

In other cases such as using a delegate that doesn't accept an optional argument or when calling this method using reflection, you have to provide the optional argument.

Selman Genç
  • 100,147
  • 13
  • 119
  • 184
  • With a delegate I can or cannot do this? – h bob Jan 28 '15 at 18:52
  • @hbob **can't**. You have to pass whatever the delegate expects. but ofcourse there are workarounds as already stated in Servy's answer. – Selman Genç Jan 28 '15 at 18:53
  • 1
    @Selman22 Well, you can't do it *for a delegate of type `Func`*. You could create a delegate of the appropriate type. – Servy Jan 28 '15 at 18:55