Is it possible to use optional/default parameters in a lambda expression in c#?

12,851

Solution 1

No. The caller (the code invoking the delegate) doesn't "see" the lambda expression, so it doesn't make sense to specify the default parameter there. All the caller sees is the delegate. In your case, for example, the calling code only knows about Action<string> - how is the compiler meant to know to supply the default value that's specified by the lambda expression?

As an example of how things get tricky, imagine if this were viable. Then consider this code:

Action<string> action;
if (DateTime.Today.Day > 10)
{
    action = (string arg = "boo") => Console.WriteLine(arg); 
}
else
{
    action = (string arg = "hiss") => Console.WriteLine(arg);
}
action(); // What would the compiler do here?

Bear in mind that the argument is provided by the compiler at the call site - so what should it do with the final line?

It's a bit like having an interface and an implementation - if you have a default parameter on an interface, that's fine; if you only have it on the implementation, then only callers who know the specific implementation will see it. In the case of lambda expressions, there's really no visible implementation for the caller to use: there's just the delegate signature.

Solution 2

The lambda will match whatever the signature of the delegate it's assigned to is; without being assigned to a delegate a lambda cannot compile.

If the delegate contains optional arguments then the use of that delegate can optionally supply arguments. If the delegate doesn't, then the use of that delegate cannot omit any arguments.

While the Action and Func delegates are very handy, and can represent most signatures, they can't represent any signature with optional arguments; you must use another delegate definition for that.

Remeber, Action and Func aren't particularly special, they're just two delegates that everyone uses so that they don't need to worry about creating their own for every little thing.

Share:
12,851

Related videos on Youtube

Fraser
Author by

Fraser

github observablehq@fraserchapman bl.ocks blogspot

Updated on September 15, 2022

Comments

  • Fraser
    Fraser over 1 year

    Is there a way to use optional arguments (default parameters) with lambda expressions in c#? I have read through the documentation but can find nothing to say one way or the other.

    To illustrate, I can define simple method that uses an optional argument to supply a default value like so:

    void MyMethod(string arg = "default-value")
    { 
        Console.WriteLine(arg);
    }
    

    What I want to know is if I am able to do the same thing using a lambda expression.

    // gives a syntax error
    Action<string> MyMethod = (arg = "default") => Console.WriteLine(arg);
    

    I can work in an optional parameter with a default value using a delegate, but this seems a bit clumsy.

    delegate void MyDelegate(string arg = "default");
    MyDelegate MyMethod = arg => Console.WriteLine(arg);
    

    Alternatively I could check the parameter in the lambda body, something like...

     Action<string> MyMethod = (arg) => Console.WriteLine(string.IsNullOrEmpty(arg) ?
                                        "default" :
                                        arg);
    

    But again this seems a bit clumsy.

    Is it possible to use optional parameters to set a default value in a lambda expression in c#?

    • horgh
      horgh over 11 years
    • SLaks
      SLaks over 11 years
      That doesn't make sense. You can't call Action<String> without an argument anyway.
    • Fraser
      Fraser over 11 years
      @KonstantinVasilcov - it is not a duplicate at all - I'm specifically asking about lambda expressions - not simple methods. I thought I made that clear, sorry.
    • Fraser
      Fraser over 11 years
      @SLaks That is what I am asking - can the argument be optional. You can't call Method(string arg) without an argument either, but you can if you do Method(string arg = "default")
    • SLaks
      SLaks over 11 years
      @Fraser: Yes, but that's defined by the signature you're calling. My point is that changing the thing the Action<string> points to cannot make that legal.
    • Fraser
      Fraser over 11 years
      @SLaks ...then why not leave that as an answer to the question rather than just berating it in the comments?
  • Fraser
    Fraser over 11 years
    +1 Thanks, that does make sense. I was really just trying something and at first it seemed like it should work...