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

Fraser picture Fraser · Jan 10, 2013 · Viewed 10.9k times · Source

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#?

Answer

Jon Skeet picture Jon Skeet · Jan 10, 2013

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.