Is it possible to use optional/default parameters in a lambda expression in c#?
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.
Related videos on Youtube
Comments
-
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 over 11 yearspossible duplicate of How to pass a method with optional parameters as an argument?
-
SLaks over 11 yearsThat doesn't make sense. You can't call
Action<String>
without an argument anyway. -
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 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 doMethod(string arg = "default")
-
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 over 11 years@SLaks ...then why not leave that as an answer to the question rather than just berating it in the comments?
-
-
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...